Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #161871
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: #include <stdint.h> |
| Date | 2021-07-11 02:14 -0700 |
| Organization | A noiseless patient Spider |
| Message-ID | <86wnpx6wl1.fsf@linuxsc.com> (permalink) |
| References | <sa5vrs$7d3$1@dont-email.me> <87wnqxxoe3.fsf@nosuchdomain.example.com> <86bl7vb24m.fsf@linuxsc.com> <878s2zndzc.fsf@bsb.me.uk> |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Tim Rentsch <tr.17687@z991.linuxsc.com> writes:
>
>> Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:
>>
>> [... on printing various integer types ...]
>
> <cut>
>
>>> printf("USHRT_MAX : %u\n", (unsigned)USHRT_MAX);
>>
>> The cast in the last line is not needed.
>
> <cut>
>
>> The description of how type promotion works is right, however a
>> cast is still not needed there. The reason is that values given
>> as variadic arguments are allowed to be the corresponding signed
>> or unsigned version of the type used to get the value, and that
>> will work as long as the value is in the set of values common to
>> both types. If an unsigned short promotes to int, then its value
>> is guaranteed to be in the set of values representable by both
>> int and unsigned int, and hence using %u for an uncasted unsigned
>> short is always safe.
>
> It's safe (in practical terms) but 7.21.6.1 paragraph 8 says of the
> 'u' conversion specifier:
>
> "o,u,x,X The unsigned int argument is..."
>
> and, later, paragraph 9 says
>
> "... If any argument is not the correct type for the corresponding
> conversion specification, the behavior is undefined."
>
> So I am left wondering how one can know that int (the promoted type
> when no cast is used) is "the correct type" for the 'u' conversion
> specification.
I believe the rule about variadic arguments applying to printf
arguments is both what was intended and how the C standard is
generally read by others, including in particular implementors.
Consider two possibilities:
One: the rules for type correctness for printf arguments are
defined only by the somewhat vague phrase "the correct type" and
are different from the rules for other functions taking variadic
arguments; or
Two: the rules for type correctness for printf arguments are the
same as the rules for type correctness for other functions taking
variadic arguments (taking into account of course that different
specifiers imply different nominal argument types).
For completeness I should mention the reference Keith Thompson
pointed out, 7.16.1.1 (paragraph 2), that gives this rule for
the 'va_arg' macro, ie, that the corresponding unsigned type
is okay for a signed type specification, and vice versa, provided
the argument value given is representable in both types.
Are the rules for type correctness for printf idiosyncratic and
specific to printf, or are they the same as other variadic
functions? To me the second case seems much more likely.
Note that both gcc and clang, running with a -Wformat option
given, accept with no diagnostic a signed argument for an
unsigned specifier, and vice versa.
At this point I realized that I haven't really responded to your
implied question about "how one can know that", for example, an
int can be given for a %u conversion sequence. At least right
now I think the best answer I can give you is to think like an
implementor. The people who write the C standard aren't lawyers,
they are regular software developers, with a fair amount of
implementation experience. They aren't thinking mainly about the
words. They are, I belive, thinking first in terms of how things
are implemented, and only later about how to express that in
normal written language. If we think about it in terms of
implementation the relationship seems pretty straightforward.
The allowance for unsigned/signed interchangeability is given
explicitly in the description for va_arg; usually the C standard
avoids giving the same rule in more than one place, so it isn't
surprising that it wouldn't be repeated in the description of
arguments for *printf functions, but instead just referred to by
the phrase "the correct type". Does that make sense?
Incidentally, in C90 neither the sentence about "the correct type"
nor the extra type rules for va_arg were present. Both were added
in C99. I don't know whether that has any bearing on the question
at hand, but it's an interesting historical coincidence.
Back to comp.lang.c | Previous | Next — Previous in thread | Find similar | Unroll thread
#include <stdint.h> SIMON <invalid@invalid.invalid> - 2021-06-13 23:08 +0100
Re: #include <stdint.h> Bart <bc@freeuk.com> - 2021-06-13 23:27 +0100
Re: #include <stdint.h> Bart <bc@freeuk.com> - 2021-06-13 23:57 +0100
Re: #include <stdint.h> Philipp Klaus Krause <pkk@spth.de> - 2021-06-14 09:03 +0200
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-14 01:23 -0700
Re: #include <stdint.h> Philipp Klaus Krause <pkk@spth.de> - 2021-06-14 12:31 +0200
Re: #include <stdint.h> Bart <bc@freeuk.com> - 2021-06-14 11:54 +0100
Re: #include <stdint.h> James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-06-13 18:34 -0400
Re: #include <stdint.h> Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-06-13 23:34 +0100
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-13 17:48 -0700
Re: #include <stdint.h> Philipp Klaus Krause <pkk@spth.de> - 2021-06-14 09:09 +0200
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-14 01:24 -0700
Re: #include <stdint.h> Philipp Klaus Krause <pkk@spth.de> - 2021-06-14 12:30 +0200
Re: #include <stdint.h> Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-06-24 10:31 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-24 11:28 -0700
Re: #include <stdint.h> Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-11 02:49 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-07-11 15:30 -0700
Re: #include <stdint.h> Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-16 03:33 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-07-16 12:31 -0700
Re: #include <stdint.h> Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-09-30 07:07 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-09-30 08:42 -0700
Re: #include <stdint.h> Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-10-06 03:55 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-10-06 07:06 -0700
Re: #include <stdint.h> James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-10-06 11:47 -0400
Re: #include <stdint.h> Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-10-06 09:35 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-10-06 10:06 -0700
Re: #include <stdint.h> James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-10-06 17:40 -0400
Re: #include <stdint.h> Branimir Maksimovic <branimir.maksimovic@icloud.com> - 2021-10-06 22:14 +0000
Re: #include <stdint.h> James Kuyper <jameskuyper@alumni.caltech.edu> - 2021-10-06 20:06 -0400
Re: #include <stdint.h> Branimir Maksimovic <branimir.maksimovic@icloud.com> - 2021-10-07 02:15 +0000
Re: #include <stdint.h> Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-06-24 22:34 +0100
Re: #include <stdint.h> Öö Tiib <ootiib@hot.ee> - 2021-06-24 15:01 -0700
Re: #include <stdint.h> Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-24 15:26 -0700
Re: #include <stdint.h> Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-11 02:14 -0700
csiph-web