s
is being promoted to an int
, which here is a 4 byte type. This is happening in all 3 cases. In the first two, an int
is what printf()
will expect, as the format specifier is for a type which would be passed as an int
. However in the last case, you have given a format specifier which expects an 8-byte type.
This is invoking undefined behaviour.
In your case it appears to have read zeros in the upper bytes of the value, effectively zero-extending to 64-bits the value which was already sign-extended to 32-bits. However you can't depend on the results of doing this - it might be reading memory or a register that is not consistently initialised. Tomorrow it could be different.
The promotion of arguments is not dependent on the format string - you must always ensure that you pass the correct arguments for the format you have specified. So an int
will not be promoted to a long
. You need to convert it yourself.
A smart compiler ought to give you a warning about this.