int main()
{
unsigned int i = 12;
printf("%lu", i); // This yields a compiler warning
}
On a 32 bit platform, does using printf
with an int using %lu
result in garbage?
Only the statement "32 bit platform" doesn't mean that int
and long
both have 32 bits, as well as their unsigned
counterparts.
So yes, indeed this can happen if unsingned long
, what %lu
is made for, is longer than unsigned int
.
But even if the lengths are equal, the types are not compatible, so formally it is undefined behaviour.
If the required type and the given type are not compatible, you
have undefined behavior. It's entirely legal for a compiler to
pass type information with the value when passing a vararg, and
exploit it in va_arg
(although I don't know of any which do,
probably for historical reasons).
As for practical effects in your particular case, "%lu"
expects an unsigned long. The only other type which is
compatible is long, and then only if the actual value of the
long is non-negative. Passing it an int
is undefined
behavior, although it might work. (On most 32 bit platforms,
int
and long
have the same size and representation.)
honestly I do not understand why you should use the %lu in place of %u since you are working with an int.
%lu should be used (in its very basic explanation) for unsigned long.
It will most probably print garbage if your compiler uses (and of course it does in 99% of the situation) different storage size for int and long.
For instance, according to C standard, an unsigned int is, in terms of storage size "At least 16 bits in size. " while unsigned long is "At least 32 bits in size."
Now, let's take as an example 16 bits for int and 32 bits for long and lets' consider a untypical example where the memory is all zeroed at the moment you run the program.
You value 12 is represented in memory as:
00000000 00001100
and if you would print with an %u would result in 12:
In place, if instruct printf to print as %lu it would result that the memory taken in the printf is:
00000000 00001100 00000000 00000000
which corresponds to the long value of 786432
Edit: Passing the value of the variable to the printf function (and not the pointer (and the size) of the variable) makes the code working anyway. My previous "explanation" was mostly to explain why the warning is raised and why it is "typically" a wrong approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With