为什么如果使用优化(-O2、-O3),此代码的行为会有所不同

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

本文关键字:代码 有所不同 -O3 如果 优化 -O2 为什么      更新时间:2023-10-16

我不得不编写一些检查例程,如果使用 -O0、-O1、-O2 或 -O3,它们的行为似乎有所不同。

下面我创建了一个适用于 -O0 和 -O1 的最小示例。但是使用 -O2 或 -O3 的行为发生了变化。在 -O0 和 -O1 的情况下,for 循环递增整数,第一次达到最大值时,会发生溢出并触发检查例程。在另一种情况下,for 循环永远不会中断,尽管整数变为负数。

法典

#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;
}

为什么允许编译器对此进行优化?

尝试使用 gcc、clang 和 icc,只有 icc 在所有优化变体中都正确,而其他两个则没有。

有符号整数溢出会产生未定义的行为。 因此,编译器可以自由地按照自己的喜好实现这种情况。