2

why INT_MAX + 1 returns -2147483648? Can someone please explain why does this happen and does it have to do with 2's compliment?

1 Answers1

6

When you add 1 to INT_MAX you're actually causing signed integer overflow. Formally, this triggers undefined behavior, which means you can't depend on any specific result.

What often happens in practice is that the value will "wrap around". Assuming two's complement representation, INT_MAX is represented as 0x7fffffff. Adding 1 to this gives you 0x80000000 which is the representation of INT_MIN.

But again, this is undefined behavior. There's no guarantee that this will actually happen.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    It might be worth changing "integer overflow" to "signed integer overflow", since unsigned integer overflow has well defined behaviour in C++ and only signed int overflow causes undefined behaviour. Better to make that 100% clear in the answer. – Jesper Juhl Jul 22 '22 at 16:54
  • 1
    `often` -> `usually` ? (these days, anyway) – Paul Sanders Jul 22 '22 at 17:25
  • @PaulSanders: [Compilers may consider code which triggers undefined behavior as unreachable and optimize it away.](https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633) Therefore, I doubt it would be appropriate to use the word "usually". The word "often", as used by the answerer, seems appropriate to me. – Andreas Wenzel Jul 22 '22 at 18:55
  • @AndreasWenzel Oh, right. If you literally add `1` to `INT_MAX` then I guess that might apply. – Paul Sanders Jul 22 '22 at 19:42
  • From C++20, the standard only permits two's complement representation for the fundamental signed integral types (`signed char`, `int`, `long`, etc) so the wrap-around you describe is required. Before C++20, the standards only specified the minimum allowed ranges (and those ranges were based on allowing possibility of ones-complement representation) and the behaviour of signed integer overflow was undefined. – Peter Jul 23 '22 at 02:05
  • 1
    @Peter: Yes, you are right that C++20 requires two's complement representation. But you are wrong about wrap-around behavior now being required. Signed integer overflow still is undefined according to [§7.1 ¶4 of the ISO C++20 standard](https://timsong-cpp.github.io/cppwp/n4868/expr.pre#4), so a wrap-around is not required. The compiler could instead, for example, simply treat code with signed overflow as unreachable, and optimize it away. [§6.8.2 ¶2 of the ISO C++20 standard](https://timsong-cpp.github.io/cppwp/n4868/basic.fundamental#2) only requires wrap-around behavior for unsigned types. – Andreas Wenzel Jul 23 '22 at 03:20
  • There are still 3 different hardware implementations in play for signed integer: warp around, trap on overflow and saturating. warp around is just the most common. – Goswin von Brederlow Jul 23 '22 at 06:38