According to the C standard (6.5.2.2 paragraph 6)
If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined. If the function is defined with a type that includes a prototype, and either the prototype ends with an ellipsis (, ...) or the types of the arguments after promotion are not compatible with the types of the parameters, the behavior is undefined. If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, except for the following cases:
- one promoted type is a signed integer type, the other promoted type is the corresponding unsigned integer type, and the value is representable in both types;
- both types are pointers to qualified or unqualified versions of a character type or void.
Thus, in general, there is nothing wrong with passing an int
to a variadic function that expects an unsigned int
(or vice versa) as long as the value passed fits in both types. However, the specification for printf
reads (7.19.6.1 paragraph 9):
If a conversion specification is invalid, the behavior is undefined. If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.
No exception is made for signed/unsigned mismatch.
Does this mean that printf("%x", 1)
invokes undefined behavior?