-1

I have try to build and run this little code with gcc 8.3.0 on an x64 linux box. Both of the two output lines are 0. This seems strange to me, the first printf is straight becauese x+x+2 will overflow to 0. But I think the second printf should output 1 becase !(x+x+2)=!0=1. I have no idea about why it also output 0. Can anybody explains why?

#include <stdio.h>
#include <limits.h>
int main(int argc, char *argv[]) {
  int x = INT_MIN;
  printf("%d\n", x+x);
  printf("%d\n", !(x+x));
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • 3
    Can't reproduce with MSVC or clang-cl (both give 1 for the second output). I guess it's because signed integer overflow is undefined behaviour. – Adrian Mole Feb 14 '21 at 13:37
  • 2
    You have integer overflow. That invokes undefined behaviour. Any result is acceptable. – Jonathan Leffler Feb 14 '21 at 13:38
  • 1
    *the first printf is straight becauese x+x+2 will overflow to 0* Signed integer overflow is undefined behavior. No conclusions should be drawn from how such a program behaves, and there is no "correct" behavior. – Andrew Henle Feb 14 '21 at 13:38
  • Voting to close the question as _not reproducible_ (since this is one immanent property of _undefined behavior_). – πάντα ῥεῖ Feb 14 '21 at 13:46
  • Does this answer your question? [What is signed integer overflow?](https://stackoverflow.com/questions/46789702/what-is-signed-integer-overflow) – costaparas Feb 14 '21 at 13:49
  • @πάντα-ῥεῖ maybe closing as a duplicate about signed integer overflow is more suitable? – costaparas Feb 14 '21 at 13:50
  • @costaparas There are tons of duplicates, which all boil down to UB, hard to pick one to explain / cover all those specific situations mentioned in the quesitons. – πάντα ῥεῖ Feb 14 '21 at 13:52
  • @πάντα-ῥεῖ True, its a pretty standard question that pops up. Another related duplicate would be [Undefined, unspecified and implementation-defined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) to cover the UB component of the question. Maybe someone can mark that one & the question can be closed as a dupe of both. – costaparas Feb 14 '21 at 13:54
  • Also, just noticed, @ikezawa-ayaka you should tag the question as [tag:c] only, not [tag:c++] -- they are different languages. – costaparas Feb 14 '21 at 13:57

1 Answers1

0

C 2018 6.5 5 says:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

When INT_MIN is added to INT_MIN, the result, two times INT_MIN, is not in the range of values representable for its type, int. So the behavior is undefined.

This means the C standard does not impose any requirements on what the implementation must do. It may act differently in different situations. It may produce an int value of zero as a result. It may produce an int value that is not zero as a result. It may trap. It may discard all of your program on the branch containing the undefined behavior. It may replace all of the code on that branch with other code.

The compiler may look at x+x, which it can evaluate during compilation instead of during program execution, see that it has undefined behavior, and simply choose to replace it with whatever is “easiest” in some sense, such as zero. It can also look at !(x+x), see that it has undefined behavior, and make the same choice to replace it with zero.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312