If we assume that int
is 4 bytes and short
is 2 bytes, then the value 53191
does not fit inside a short. What happens then isn't well-defined:
Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
So it is up to the compiler to handle this situation as it sees fit. A common implementation is to treat the binary representation of the original type as the corresponding 2's complement representation of the new type. In this case 0xCFC7
which gets treated as a short
with value -12345.
Next up, %x
assumes a parameter of type unsigned int
. printf("s = %x",s);
is therefore not well-defined either - it's strictly speaking undefined behavior.
In practice, s
will get promoted as required by "the default argument promotions" that apply to all variadic functions like printf. That is, from short
to int
. Then a common non-standard extension is to reinterpret the binary representation of that promoted int
as unsigned int. In case this happens, we would observe the sign extension that took place during argument promotion, meaning the value would have changed from 0xCFC7
to 0xFFFFCFC7
. But to print an int
with %x
isn't guaranteed behavior so we shouldn't rely on it or write code such as this.