Please have a look at this code:
#include <stdio.h>
int main(void)
{
short s = -1;
printf("sizeof(short) = %lu\n", sizeof(short));
printf("sizeof(int) = %lu\n", sizeof(int));
printf("sizeof(long) = %lu\n", sizeof(long));
printf("s = %hd\n", s);
printf("s = %d\n", s);
printf("s = %ld\n", s);
return 0;
}
It gave output as :
sizeof(short) = 2
sizeof(int) = 4
sizeof(long) = 8
s = -1
s = -1
s = 4294967295
In last line why s = 4294967295 instead of s = -1 as through this question I came to know that In C when variable gets promoted, its value remains constant.
sis being promoted to anint, which here is a 4 byte type. This is happening in all 3 cases. In the first two, anintis whatprintf()will expect, as the format specifier is for a type which would be passed as anint. 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
intwill not be promoted to along. You need to convert it yourself.A smart compiler ought to give you a warning about this.