Overflowing an integer is undefined behavior. Then the compiler is allowed to assume you are not going to overflow integers and optimize accordingly.
I was doing some delicate bit-fiddling code and got a surprise, that if you put in a file this
#include <stdint.h>
void consume(bool);
extern long maxInt;
bool noUndefinedBehavior() {
maxInt = static_cast<unsigned long>(long{-1}) >> 1;
consume(INT64_MAX == maxInt);
long minInt = static_cast<unsigned long>(maxInt) + 1;
return minInt < 0;
}
bool undefinedBehavior() {
maxInt = static_cast<unsigned long>(long{-1}) >> 1;
consume(INT64_MAX == maxInt);
auto minInt = maxInt + 1;
return minInt < 0;
}
then define in another .cpp file some consume
function and long maxInt
; then build with -O2
, and you'll see undefinedBehavior
returns false!