Spoon said:
(Hair-splitting ahead) AFAIU, for the value 42, int and unsigned int
are equivalent because both conversions are well-defined.
Conversion has nothing to do with it. Conversion between int and
double is well-defined, but passing a double argument for a "%d"
format invokes undefined behavior. No conversion, other than argument
promotions, occurs for variadic arguments.
It's true that the value 42 is guaranteed to have the same
*representation* in types int and unsigned int. Specifically, C99
6.2.5p9 says:
The range of nonnegative values of a signed integer type is a
subrange of the corresponding unsigned integer type, and the
representation of the same value in each type is the same.
with a footnote:
The same representation and alignment requirements are meant to
imply interchangeability as arguments to functions, return values
from functions, and members of unions.
So you can look carefully through the standard for proof that the code
will work properly whether the argument is promoted to int or to
unsigned int (note that this depends on a footnote, which is
nonnormative). Note that you'll also need to depend on the
implementer getting this right. It's also likely that the argument
will be promoted to int on all the platforms you use, so you'll never
have a chance to test the case where it's promoted to unsigned int,
just in case you missed something.
Or you can write simpler code that doesn't depend on a potentially
shaky line of reasoning.
u is, in fact, an uint16_t and I don't know for sure that u is an
unsigned short int. It might be an unsigned int.
So convert it to unsigned int and use "%u".
Incidentally, there's another subtle issue here. The standard's
description of printf() describes the required formats for various
types. It's almost certainly safe to assume that printf() uses the
same mechanisms as a user-written variadic function, so you can safely
assume that argument promotion occurs as you would expect. But the
standard doesn't *quite* come out and say so. (There was a lengthy
discussion of this in comp.std.c a while ago.) I don't think it's
anything to worry about, but it's enough to make me more cautious with
format strings than I absolutely need to be.