0

Why is it possible to store -32 768 as a short int?

printf("%hd", -32768);
//returns -32768, no compiler errors

printf("%hd", (short int)-32768);
//returns -32768, no compiler errors

short int a = -32768;
printf("%hd", a);
//returns -32768, no compiler errors

printf("%d", -2147483648);
//compiler returned error as it should

And why doesn't short int overflow throw an error in the compiler?

printf("%hd", -32769);
//returns 32767, no compiler errors

while

printf("%d", -2147483648);
//compiler returned error

I am using 64 bit ubuntu 16.04 with the gcc compiler version 5.4.0. It has something to do with the printf function? or I don't understand something.

  • If printf _returns_ a negative number it means something went wrong. Probably you mean it _prints_ those numbers and does not _return_ them? – Lukas-T Jan 13 '20 at 21:03
  • 2
    When you don't tell the truth to `printf` about the types you're printing, the behavior is undefined. – PaulMcKenzie Jan 13 '20 at 21:05
  • Looks like a GCC "bug". Clang does the right thing. – NathanOliver Jan 13 '20 at 21:08
  • According to this https://stackoverflow.com/questions/589575/what-does-the-c-standard-state-the-size-of-int-long-type-to-be I shouldn't be able to store such value, but for some reasons it can print this one extra value with is -32768 – Patryk Banaś Jan 13 '20 at 21:10
  • `//compiler returned error as it should` -- I don't understand the issue. You're calling the `printf` function, a function that knows nothing about the types you're sending, and is trusting you, the programmer, to give it the right types. If you don't give it the types expected, then the behavior is undefined. – PaulMcKenzie Jan 13 '20 at 21:19
  • I just didn't understand why short int is treated differently than an int in this case – Patryk Banaś Jan 13 '20 at 21:29
  • I just have the option to use this last value while with other types of variables I don't have that option, and printf has it highlighted that it should read a value of type short int %hd – Patryk Banaś Jan 13 '20 at 21:34
  • I guess printf just take every value but when they are 32 bit integers or above then will throw error in compiler – Patryk Banaś Jan 13 '20 at 21:43

1 Answers1

1

There's nothing magic about passing those values to printf. Remember, its prototype is int printf(const char*, ...). When a numeric argument that's smaller than int is passed through an ellipsis (the ... at the end of the argument list) it gets promoted to int. So printf expects all values whose types are smaller than int to be passed as int.

However, in this case, there are no integral promotions involved. The type of -32768 is int. Same for -32769. It's up to the code inside printf to apply the format specifier (here, "%hd") and try to make sense out of the values that are passed to it. This code passes integer values and claims that their type is short. It looks like it works, but, in general, don't expect sense from that.

Concerning (short)-32768, if that value fits in a short (which it probably does; check SHORT_MIN to find out), no problem. If not, the result of the conversion is implementation-defined; it's not illegal.

And, finally, -32769 has type int; there's no overflow, and the result that you're seeing is just the formatting code trying to make sense out of the bit pattern, on the assumption that the value it sees is the result of promoting a short to int. Again, don't expect sense from that.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165