Reputation: 1144
I would like to know, as per C specification, what is the expected behavior in C if the given data type does not match the format specifier expected. For eg:
printf("%lu\n", 2);
Upvotes: 1
Views: 1311
Reputation: 153468
It is undefined behavior. @Weather Vane
2
is an decimal integer constant with a value of 2 and type of int
.
When 2
is passed to ...
part of printf(const char * format, ...);
it undergoes default argument promotions , which in this case is int
stays an int
. printf()
receives the 2
as an int
.
"%ld"
expects to match a long
. As long
and int
are different types:
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined. C11dr §7.21.6.1 9
Even if the size and range of long
and int
are the same, the result is still UB - although there is debate on this point. On many platforms, the UB is acceptable. In any case, this code should be avoided.
A well enabled compiler will warn of the mis-match.
Alternatives:
printf("%d\n", 2);
printf("%lu\n", 2ul);
printf("%lu\n", 2UL);
printf("%lu\n", 1ul * 2);
printf("%lu\n", (undersigned long) 2);
Upvotes: 2
Reputation: 645
The type will be promoted per the normal promotion rules (plus two exceptions) if possible. If the promotion is not possible, the behavior is undefined in C11 per 7.16.1.1 (emphasis mine):
The va_arg macro expands to an expression that has the specified type and the value of the next argument in the call. The parameter ap shall have been initialized by the va_start or va_copy macro (without an intervening invocation of the va_end macro for the same ap). Each invocation of the va_arg macro modifies ap so that the values of successive arguments are returned in turn. The parameter type shall be a type name specified such that the type of a pointer to an object that has the specified type can be obtained simply by postfixing a * to type. If there is no actual next argument, or if type is not compatible with the type of the actual next argument (as promoted according to the default argument promotions), the behavior is undefined, except for the following cases:
one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types;
one type is pointer to void and the other is a pointer to a character type.
Upvotes: 7