If I wished to use the <limits> header, it would be easy to write the smallest integer:
std::int32_t small = std::numeric_limits<std::int32_t>::min();
This makes small equal to -2147483648.
I'm working in a library where such numbers are spelled out. Thus it would be preferred to write
std::int32_t small = -2147483648;
I'm having trouble with this on Visual Studio, but when I read the C++ spec, I find it suggests that I can't do this for any compiler. The reason I think I can't do this is that the spec indicates that a integer-literal does not include the negative sign. The negative sign actually becomes a unary-minus later. So C++ processes the integer literal 2147483648. This number is too large to fit in an int (assuming int is 32-bits, which it is on the platform I'm considering), so it must be a long int (64-bits).
(Incidentally, this is where I run awry on visual studio. It appears to treat 2147483648 as an unsigned long, rather than a signed long, but this question is about the spec behavior)
From what I can see, there's no way to write the 32 bit number -2147483648 as a 32-bit literal. You have to make it a 64-bit literal first, 2147483648UL, then negate it. This seems like an oversight, but it also seems to compile everywhere (except Visual Studio), so what did I miss?
Trivial solution is to bitwise invert the maximum value of the proper type. Given all the fixed width types are guaranteed to use two's complement representation, bitwise invert of the largest maximum value will always produce the most negative value (negation is the same as flipping all the bits and adding one; invert omits the adding one step, so you end up with a negative number one further from zero), so you can reliably do:
The
INT32_Cis function macro to make an integer constant of the correct size (it'll usually expand to nothing, making it~2147483647, unlessinton your system is not the same size asint32_t).