4

I understand the reason why C++ define INT_MIN as (-2147483647 - 1), but why don't they just use 1<<31 ? That prevent the overflow and also easy to understand.

Jun
  • 426
  • 1
  • 7
  • 16
  • Personally, I find just as surprising that defining it as `-2147483648` would fail. I mean, it **is** the exact value, but compilers will complain it's out of range. Honestly, it's stupid. – Matthieu M. Jun 02 '13 at 18:54
  • @MatthieuM. How can it be in range? It's after all `-(2147483648)`, and `2147483648` is definitely larger than `INT_MAX` on a 32 bits platform. – MSalters Jun 02 '13 at 22:21
  • @MSalters: Maybe then the `-` should be part of the numeric literal ? – Matthieu M. Jun 03 '13 at 06:12
  • @MatthieuM. Would that also apply to `- 123` ? I.e. is the space part of the oken? Such changes are rarely as simple as they look. You'd have to prove that no reasonable program would be affected. – MSalters Jun 04 '13 at 19:52
  • @MSalters: Oh, I do know that changing it now is probably impossible (and of course a space breaks a token, after all `1 2 3` is not `123`); I am merely criticizing the original decision. – Matthieu M. Jun 05 '13 at 06:42

2 Answers2

7

That prevent the overflow and also easy to understand

How could it prevent the overflow, if by left-shifting a positive number you are trying to obtain a negative one? ;)

Keep in mind, that signed integer overflow is Undefined Behavior. Per paragraph 5.8/2 of the C++11 Standard:

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. [...] Otherwise, if E1 has a signed type and non-negative value, and E1×2^E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

Also, per paragraph 5/4:

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [...]

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • @Guillaume: No, the same paragraph makes that undefined as well. – Oliver Charlesworth Jun 02 '13 at 16:08
  • @Guillaume: I don't think so. If `E1` is negative, the "otherwise" clause applies – Andy Prowl Jun 02 '13 at 16:10
  • "If `E1` has a signed type **and non-negative value**..." – cHao Jun 02 '13 at 16:11
  • @cHao: Was that for Guillaume? – Andy Prowl Jun 02 '13 at 16:12
  • @AndyProwl: Yeah, apparently. :) – cHao Jun 02 '13 at 16:13
  • Since `INT_MIN` is defined by the implementation, "Undefined Behavior" is perfectly OK. Pretty much every implementation of `offset_of` relies on it, as do varargs. – MSalters Jun 02 '13 at 22:23
  • @AndyProwl: Thanks. According to the standard you quoted, if I use `unsigned int x = (1<<31)`, it is not undefined behavior; but `int x = (1<<31)` is undefined behavior. But for the latter case, I'm still 100% getting INT_MIN assigned to variable x right(which is what I want)? Does it violate anything or screw up anything? – Jun Jun 03 '13 at 02:11
  • @Jun: Why `1 << 31`? Did you mean perhaps `-1 << 31`? But then notice, that `-1` is still `int` and still negative, so it does not matter whether you are then assigning the result of `-1 << 31` to an `unsigned int`: the evaluation of `-1 << 31` is UB – Andy Prowl Jun 03 '13 at 17:40
  • @AndyProwl: Let me clarify and correct me if wrong: So the reason I raised this question is because I want to get `-2147483648` in my program. Because `1<<31` is `0x80000000` in hex. If we interpret it as an signed integer using 2's complement, it should be `-2147483648`, which is my goal. So essentially I'm asking is there any difference between `int x = (1<<31)` and `int x = (-2147483647 - 1)` The former one surely has UB but it still generate correct result right? – Jun Jun 03 '13 at 20:16
  • @Jun: The sentence "The former one surely has UB but it still generate correct result" is an oxymoron. You can't analyze UB. UB is UB. It may give the result you expect on your compiler, on your architecture, on your environment, and not in a different one. – Andy Prowl Jun 03 '13 at 20:18
  • Note: In C++14 this was [changed to implementation-defined](http://stackoverflow.com/questions/26331035/why-was-1-31-changed-to-be-implementation-defined-in-c14). In a comment, Howard Hinnant explains that the change was made because he was tired of having to write `-2147483647 - 1`. – M.M Apr 10 '15 at 00:05
4

Because 1 << 31 invokes undefined behaviour (assuming 32-bit int).

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680