2

Suppose that on a platform, the minimal signed value is −2^15 = −32768 and the maximum value is 2^15 −1 = 32767. The constant 32768 then doesn’t fit into signed and is thus signed long. As a consequence, the expression -32768 has type signed long. Thus the minimal value of the type signed on such a platform cannot be written as a literal constant.

From Modern C by Jens Gustedt.

It's trivial to understand why 32768 is signed long, but why is -32768 also signed long and not signed, given the minimum signed value of -32768?

dbush
  • 205,898
  • 23
  • 218
  • 273
dexter
  • 185
  • 8
  • 6
    https://stackoverflow.com/a/41407498/635608 – Mat Nov 21 '21 at 12:47
  • If you have 16 bits signed, then 1 in most significant bit means < 0, so max int is 7FFF (01111111 11111111) = 32767 and min value is 8000 (10000000 00000000) = -32768 – Ptit Xav Nov 21 '21 at 12:58
  • 3
    *Thus the minimal value of the type signed on such a platform cannot be written as a literal constant* This is not limited to the minimal value, no strictly negative value can be written as a literal constant: `-1` is not a literal constant, it is a constant expression. – chqrlie Nov 21 '21 at 13:16
  • 1
    Operators like unary minus `-` may *promote* their arguments to a wider type, but will never *demote* them to a narrower type, even if the result of the operation would fit in the narrower type. So `32768` is of type `signed long`, and even though the result of `-32768` would fit in `signed`, the compiler won't demote the result to that type. – Nate Eldredge Nov 21 '21 at 15:10

3 Answers3

3

Because -32768 is the positive literal 32768 (which does not fit into a 16-bit value and therefore must be represented by the next larger type), to which then the unary minus is applied (which does not change the type).

If you write e.g. ( ( - 32767 ) - 1 ), you get your constant in int type.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • i don't get the latter i.e. why'll ((-32767)-1) have the type int? – dexter Nov 21 '21 at 15:18
  • @dexter: Positive 32768 does not fit into a 16bit int, so the constant is long on a 16bit platform *before* the unary minus turns it negative. 32767 *does* fit into int, gets turned negative by the unary minus, and then you are free to substract one more to get negative 32768 without keaving the range of int. – DevSolar Nov 21 '21 at 17:34
  • @DevSolar [Why do we define `INT_MIN` as `-INT_MAX - `1?](https://stackoverflow.com/q/26003893/995714) – phuclv Nov 22 '21 at 00:42
  • @phuclv: Yes, pretty much exactly. – DevSolar Nov 22 '21 at 08:42
2

If int is a 16-bit type in your platform then 32768 doesn't fit in it. Therefore 32768 must have the next larger type which is long. -32768 isn't a negative integer literal but a unary minus applied to the literal 32768. Since 32768 is long, so is -32768

This is exactly the same as

phuclv
  • 37,963
  • 15
  • 156
  • 475
2

-32768 is not actually an integer literal. It's the integer literal 32768 with the unary - operator applied to it.

Since on this system the value 32768 is outside the range of int, the constant 32768 has type long. Applying the unary - to a value of type long results in an expression of type long, therefore -32768 has type long.

A way to get the value -32768 with type int, the proper expression would be -32767 - 1. The integer constant 32767 has type int. Applying the unary - operator to it still gives us a value in the range of int, then subtracting 1 gives us an expression of type int with value -32768.

dbush
  • 205,898
  • 23
  • 218
  • 273