Rule one: The chances of you finding a bug in the library or the compiler are very, very slim. Always assume the compiler / library is right.
Parameters are passed to printf()
through the mechanisms in <stdarg.h>
(variable argument lists), which involves some magic on the stack.
Without going into too much detail, what printf()
does is assuming that the next parameter it has to pull from the stack is of the type specified in your format string - in the case of %d
, a signed int.
This works if the actual value you've put in there is smaller or equal in width to int
, because internally any smaller value passed on the stack is extended to the width of int
through a mechanism called "integer promotion".
This fails, however, if the type you have passed to printf()
is larger than int
: printf()
is told (by your %d
) to expect an int
, and pulls the appropriate number of bytes (let's assume 4 bytes for a 32 bit int
) from the stack.
In case of your long long
, which we'll assume is 8 bytes for a 64 bit value, this results in printf()
getting only half of your long long
. The rest is still on the stack, and will give pretty strange results if you add another %d
to your format string.
;-)