F
Flash Gordon
Keith Thompson wrote, On 23/01/07 17:56:
Possibly they did it because it was simpler than making it undefined for
integers outside the range of short (the library might take advantage of
the limited range to do something that won't work with a larger range)
and undefined to pass int instead of long or long instead of int etc.
After all, why would you use %hd when you are actually going to be
passing an int that could be out of range for a short?
Old Wolf said:You caused undefined behaviour by not passing an argument of
type 'short int' to %hd
Interesting.
In the description of fprintf(), C99 7.19.6.1p7 says that the 'h'
modifier
Specifies that a following d, i, o, u, x, or X conversion
specifier applies to a short int or unsigned short int argument
(the argument will have been promoted according to the integer
promotions, but its value shall be converted to short int or
unsigned short int before printing);
[...]
and p9 says:
[...] If any argument is not the correct type for the
corresponding conversion specification, the behavior is undefined.
But is the "correct type" for "%hd" short, or is it int?
If the correct type is short, then the following two calls:
printf("%hd\n", (short)42);
printf("%hd\n", 42);
can behave differently, and the latter invokes undefined behavior.
For any user-written variadic function that uses <stdarg.h>, the two
calls are identical; the "(short)42)" argument is promoted to int
before the call.
The standard doesn't say that printf() uses <stdarg.h>. Conceivably
the compiler could treat printf() specially, but it would be difficult
(but not impossible) to do this for calls through a pointer, where the
compiler doesn't know whether it's calling printf() or an equivalent
user-defined variadic function.
Things would be more consistent if the "correct type" for "%hd" were
int rather than short.
Possibly they did it because it was simpler than making it undefined for
integers outside the range of short (the library might take advantage of
the limited range to do something that won't work with a larger range)
and undefined to pass int instead of long or long instead of int etc.
After all, why would you use %hd when you are actually going to be
passing an int that could be out of range for a short?