Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #91655 > unrolled thread
| Started by | Johann Klammer <klammerj@NOSPAM.a1.net> |
|---|---|
| First post | 2016-08-04 18:11 +0200 |
| Last post | 2016-08-05 08:26 -0700 |
| Articles | 11 — 4 participants |
Back to article view | Back to comp.lang.c
Q: stdint format specifiers Johann Klammer <klammerj@NOSPAM.a1.net> - 2016-08-04 18:11 +0200
Re: Q: stdint format specifiers supercat@casperkitty.com - 2016-08-04 09:53 -0700
Re: Q: stdint format specifiers Keith Thompson <kst-u@mib.org> - 2016-08-04 12:44 -0700
Re: Q: stdint format specifiers Johann Klammer <klammerj@NOSPAM.a1.net> - 2016-08-04 22:57 +0200
Re: Q: stdint format specifiers supercat@casperkitty.com - 2016-08-04 14:11 -0700
Re: Q: stdint format specifiers Keith Thompson <kst-u@mib.org> - 2016-08-04 14:19 -0700
Re: Q: stdint format specifiers supercat@casperkitty.com - 2016-08-04 15:08 -0700
Re: Q: stdint format specifiers Keith Thompson <kst-u@mib.org> - 2016-08-04 15:26 -0700
Re: Q: stdint format specifiers Malcolm McLean <malcolm.mclean5@btinternet.com> - 2016-08-04 23:19 -0700
Re: Q: stdint format specifiers supercat@casperkitty.com - 2016-08-05 08:04 -0700
Re: Q: stdint format specifiers Keith Thompson <kst-u@mib.org> - 2016-08-05 08:26 -0700
| From | Johann Klammer <klammerj@NOSPAM.a1.net> |
|---|---|
| Date | 2016-08-04 18:11 +0200 |
| Subject | Q: stdint format specifiers |
| Message-ID | <nnvpf7$1ojc$1@gioia.aioe.org> |
Does anyone have a coccinelle script to fixup *printf format specifiers to those pesky PRI*** ones? I could not find one on coccinellery <http://coccinellery.org/>.
[toc] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-04 09:53 -0700 |
| Message-ID | <282c43f4-9e51-4c3c-9552-6703c60df230@googlegroups.com> |
| In reply to | #91655 |
On Thursday, August 4, 2016 at 11:11:29 AM UTC-5, Johann Klammer wrote: > Does anyone have a coccinelle script to fixup *printf format specifiers to > those pesky PRI*** ones? I could not find one on coccinellery <http://coccinellery.org/>. Such a thing will likely be difficult unless one can keep track of types in more detail than most compilers do. If a particular compiler defines "int32_t" as an alias for "long", then "%ld" would likely get used on that compiler as the formatting code for both "int32_t" and "long". Unless a conversion tool can keep track of which 32-bit variables are actually of type "uint32_t", it would have no way of knowing which ones should be printed out using a "%ld" specifier and which ones require the PRI_* macros.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-08-04 12:44 -0700 |
| Message-ID | <ln8twc1fpw.fsf@kst-u.example.com> |
| In reply to | #91658 |
supercat@casperkitty.com writes:
> On Thursday, August 4, 2016 at 11:11:29 AM UTC-5, Johann Klammer wrote:
>> Does anyone have a coccinelle script to fixup *printf format specifiers to
>> those pesky PRI*** ones? I could not find one on coccinellery <http://coccinellery.org/>.
>
> Such a thing will likely be difficult unless one can keep track of types
> in more detail than most compilers do. If a particular compiler defines
> "int32_t" as an alias for "long", then "%ld" would likely get used on that
> compiler as the formatting code for both "int32_t" and "long". Unless
> a conversion tool can keep track of which 32-bit variables are actually
> of type "uint32_t", it would have no way of knowing which ones should be
> printed out using a "%ld" specifier and which ones require the PRI_* macros.
To be clear, assuming int32_t is a typedef for long, there is no
distinction between a variable of type int32_t and a variable of type
long. int32_t is not a distinct type with the same characteristics as
long; it's a different name for exactly the same type.
Certainly a tool *could* keep track of which typedef is used to define
an object, and choose a printf format based on that. (It would be
tracking additional information that's not defined by the C language;
nothing wrong with that.)
Without that ability, it could use "%ld" for any argument of type
long, whether it was defined using the name "long" or the name
"int32_t". But then the resulting code (assuming you're trying
to generate C source code) wouldn't be portable; it could fail
when compiled for a system where int32_t is an alias for int, and
long is 64 bits. (Unless you regenerate the source code for each
target system; is that an option?)
It's an interesting problem, and not one that the C language gives you a
lot of help with.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Johann Klammer <klammerj@NOSPAM.a1.net> |
|---|---|
| Date | 2016-08-04 22:57 +0200 |
| Message-ID | <no0a80$jo9$2@gioia.aioe.org> |
| In reply to | #91672 |
On 08/04/2016 09:44 PM, Keith Thompson wrote: [...] > > Without that ability, it could use "%ld" for any argument of type > long, whether it was defined using the name "long" or the name > "int32_t". But then the resulting code (assuming you're trying > to generate C source code) wouldn't be portable; it could fail > when compiled for a system where int32_t is an alias for int, and > long is 64 bits. (Unless you regenerate the source code for each > target system; is that an option?) > Yes, you are right. I'll need a different tool...
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-04 14:11 -0700 |
| Message-ID | <ad7f21a6-cd3b-450b-b625-a64fd3f4bdbd@googlegroups.com> |
| In reply to | #91672 |
On Thursday, August 4, 2016 at 2:44:52 PM UTC-5, Keith Thompson wrote: > Without that ability, it could use "%ld" for any argument of type > long, whether it was defined using the name "long" or the name > "int32_t". But then the resulting code (assuming you're trying > to generate C source code) wouldn't be portable; it could fail > when compiled for a system where int32_t is an alias for int, and > long is 64 bits. (Unless you regenerate the source code for each > target system; is that an option?) From what I can tell, the fundamental purpose of all the PRI_* macros is to make code that uses types like uint32_t behave in a fashion independent of the size of the built-in integer types; the main reason one would want to convert code from using %ld to using those macros is to facilitate migration of that code to other systems. If integer types change, some format specifiers will need to change while others won't, and there's no easy way to specify which. BTW, many such headaches could have been avoided if the Standard had made it possible for variadic functions to include a list of supported types, with other types being converted to supported types when possible. Since printf is often used in situations that aren't performance-critical, many implementations could have specified that all integer-type arguments will be promoted to the longest integer type, which would then allow them to ignore the type-length characters altogether.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-08-04 14:19 -0700 |
| Message-ID | <lnziosz0xx.fsf@kst-u.example.com> |
| In reply to | #91682 |
supercat@casperkitty.com writes:
> On Thursday, August 4, 2016 at 2:44:52 PM UTC-5, Keith Thompson wrote:
>> Without that ability, it could use "%ld" for any argument of type
>> long, whether it was defined using the name "long" or the name
>> "int32_t". But then the resulting code (assuming you're trying
>> to generate C source code) wouldn't be portable; it could fail
>> when compiled for a system where int32_t is an alias for int, and
>> long is 64 bits. (Unless you regenerate the source code for each
>> target system; is that an option?)
>
> From what I can tell, the fundamental purpose of all the PRI_* macros is
> to make code that uses types like uint32_t behave in a fashion independent
> of the size of the built-in integer types; the main reason one would want
> to convert code from using %ld to using those macros is to facilitate
> migration of that code to other systems.
Right. I wasn't discussing the purpose of the PRI_* macros, just the
problems inherent in automatically generating code that uses them.
Strictly speaking it's not just the *sizes* of the built-in types. For
example, even if int and long both happen to be 32 bits, using "%d" with
a long argument or "%ld" with an int argument still has undefined
behavior (regardless of whether the declaration used "int", "int32_t",
or some other name). The symptom of the UB is likely to be that it
"works", but it's still UB.
> If integer types change, some
> format specifiers will need to change while others won't, and there's no
> easy way to specify which.
Which is pretty much what I said.
> BTW, many such headaches could have been avoided if the Standard had made
[snip]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-04 15:08 -0700 |
| Message-ID | <ba812915-8a2f-4dcb-a86f-ccdff66d5df8@googlegroups.com> |
| In reply to | #91684 |
On Thursday, August 4, 2016 at 4:19:59 PM UTC-5, Keith Thompson wrote:
> Strictly speaking it's not just the *sizes* of the built-in types. For
> example, even if int and long both happen to be 32 bits, using "%d" with
> a long argument or "%ld" with an int argument still has undefined
> behavior (regardless of whether the declaration used "int", "int32_t",
> or some other name). The symptom of the UB is likely to be that it
> "works", but it's still UB.
Indeed, it would be hard for an implementation of printf to fetch the
argument for %d or %ld without using a pointer of type "int*" or "long*"
to read it, and it has become fashionable for compilers to assume that
an int* cannot modify a "long", and a "long*" cannot modify an "int",
even on platforms where both types have identical representations. I
wish the authors of the Standard had been interviewed back in 1989 as
to whether the Standard refrains from allowing objects to be accessed
via pointers to types with equivalent representations because
(1) Such rules wouldn't be applicable to all implementations (on some
implementations, every type has a different representation), and the
authors of the Standard expected that compiler writers would
recognize the aliasing on platforms where it would be sensible to
do so even without the Standard mandating it, or
(2) They wanted to allow programmers to tell the compiler that variables
used for different purposes wouldn't alias by using different types
for different purposes.
While it's plausible that at least some of the committee members may have
intended #2, I've seen no evidence of that having been anything near a
consensus viewpoint. It would be interesting to know how many of the
Committee members would have regarded alias-incompatibility of types with
matching representations as a sign of a high-quality compiler or a low-
quality compiler.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-08-04 15:26 -0700 |
| Message-ID | <lnr3a4yxvp.fsf@kst-u.example.com> |
| In reply to | #91686 |
supercat@casperkitty.com writes:
> On Thursday, August 4, 2016 at 4:19:59 PM UTC-5, Keith Thompson wrote:
>> Strictly speaking it's not just the *sizes* of the built-in types. For
>> example, even if int and long both happen to be 32 bits, using "%d" with
>> a long argument or "%ld" with an int argument still has undefined
>> behavior (regardless of whether the declaration used "int", "int32_t",
>> or some other name). The symptom of the UB is likely to be that it
>> "works", but it's still UB.
>
> Indeed, it would be hard for an implementation of printf to fetch the
> argument for %d or %ld without using a pointer of type "int*" or "long*"
> to read it, and it has become fashionable for compilers to assume that
> an int* cannot modify a "long", and a "long*" cannot modify an "int",
> even on platforms where both types have identical representations.
Good.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2016-08-04 23:19 -0700 |
| Message-ID | <f0f7b353-f070-4a17-a401-4952372d4be2@googlegroups.com> |
| In reply to | #91684 |
On Thursday, August 4, 2016 at 10:19:59 PM UTC+1, Keith Thompson wrote: > supercat@casperkitty.com writes: > >> From what I can tell, the fundamental purpose of all the PRI_* >> macros is to make code that uses types like uint32_t behave in >> a fashion independent of the size of the built-in integer types; >> the main reason one would want to convert code from using %ld to >> using those macros is to facilitate >> migration of that code to other systems. > > Right. I wasn't discussing the purpose of the PRI_* macros, just the > problems inherent in automatically generating code that uses them. > Yes, you don't want to play with fundamental things like strings or integers, or the language starts to fall apart and the most trivial task becomes involved. Make int big enough to index any array, and stop using all other types except in special purpose bit-bashing or port communicating code.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2016-08-05 08:04 -0700 |
| Message-ID | <170d8aae-164a-4bc2-b95c-800c7113f92f@googlegroups.com> |
| In reply to | #91701 |
On Friday, August 5, 2016 at 1:19:33 AM UTC-5, Malcolm McLean wrote: > Make int big enough to index any array, and stop using all other > types except in special purpose bit-bashing or port communicating > code. Having 32-bit operations be just as cheap as 16-bit operations makes that approach much more practical. Unfortunately, C never made any real distinction between types that are expected to hold numbers and types that are expected to hold combinations of bits that will be interchanged with other devices, with promotions being limited on the latter types. A lot of extant code needs a 32-bit type that wraps mod 4294967296, and migration of such code to platforms with 64-bit "int" would be greatly eased if such platforms were allowed to have a type that behaves much as uint32_t does *on 32-bit, 16-bit, or 8-bit platforms* (among other things, having operations upon two values of that type yield a result of the same type).
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2016-08-05 08:26 -0700 |
| Message-ID | <lneg63z16n.fsf@kst-u.example.com> |
| In reply to | #91701 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Thursday, August 4, 2016 at 10:19:59 PM UTC+1, Keith Thompson wrote:
>> supercat@casperkitty.com writes:
>>> From what I can tell, the fundamental purpose of all the PRI_*
>>> macros is to make code that uses types like uint32_t behave in
>>> a fashion independent of the size of the built-in integer types;
>>> the main reason one would want to convert code from using %ld to
>>> using those macros is to facilitate
>>> migration of that code to other systems.
>>
>> Right. I wasn't discussing the purpose of the PRI_* macros, just the
>> problems inherent in automatically generating code that uses them.
>>
> Yes, you don't want to play with fundamental things like strings
> or integers, or the language starts to fall apart and the most
> trivial task becomes involved.
> Make int big enough to index any array, and stop using all other
> types except in special purpose bit-bashing or port communicating
> code.
Feel free to argue that, but please don't frame it as if you were
agreeing with me.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web