I had to code some checking routines and they appear to behave differently if one uses -O0, -O1, -O2 or -O3.
Below I created a minimal example that works fine for -O0 and -O1. But using -O2 or -O3 the behavior changed. In the -O0 and -O1 case, the for-loop increments the integer and the first time it gets to the maximum, the overflow happens and the check routine triggers. In the other case the for-loop never breaks, although the integer gets negative.
Code
#include <iostream>
inline bool check(const int i) {
if (i < 0)
return false;
else
return true;
}
int main() {
for (int i = 0;; i += 50000000) {
std::cout << i << std::endl;
const bool succ = check(i);
if (succ == false) {
std::cout << "Overflow: " << i << std::endl;
break;
}
}
return 0;
}
Why is the compiler allowed to optimize this away?
Trying with gcc, clang and icc, only the icc does it correct in all optimization variants the other two did not.