Sun, 10 Feb 2013 19:37:29 +0000

So, another fun fact about C. You'd think that a language would make it possible to express any value for its in-built types as a simple constant expression. Of course, you can't do that in C.

In C you can express both signed and unsigned integer of any of the
integer types. For example `5`

is a signed integer; `5L`

is a signed long, `5U`

is an unsigned integer. But, there is no
way to expression a negative number as a constant! Despite what you might easily
assume, `-5`

is not constant, rather it is the unary `-`

operator applied to the constant `5`

. Now, generally this doesn't
cause any problems. Unless of course, you care about types and care about
having programs that are valid according to the standard.

So, assuming two's complement 32-bit integers, if you want an
expression that has the type `int`

and the minimum value
(`-2147483648`

), then you need to be careful. If you choose
the straight-forward approach you'd write this as
`-2147483648`

, and you'd be wrong. Why? Well, the integer
constant `2147483648`

has the type `long`

, since
it can not be represented as an integer (the maximum value of a 32-bit
integer is 2147483647). So, the type of an expression of the form
`- <long>`

is, of course `long`

. So, what
can we do instead? Well, there are lots of approaches, but probably
the simplist is: `-2147483647 - 1`

. In this case,
`2147483647`

can be represented as an integer,
`-2147483647`

, is still of type `int`

, and then
you can safely subtract 1.

Of course, this becomes even more interesting is you are dealing
with the type `long long`

. Assuming a two's complement,
64-bit type, then the minimum value is
`-9223372036854775808`

, but of course, you can't just write
`-9223372036854775808LL`

, since
`9223372036854775808LL`

can't be represented by the type
`long long`

(and assuming the implementation doesn't define
any extended integer types), this would actually be an invalid C
program.