Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code behave differently if optimizing (-O2, -O3) is used?

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.

like image 477
Chris Avatar asked Dec 20 '13 15:12

Chris


1 Answers

Signed integer overflow gives undefined behavior. Thus, the compiler has free reign to implement this case as they like.

like image 119
Joe Z Avatar answered Nov 07 '22 04:11

Joe Z