如果使用优化(-O2,-O3),为什么此代码的行为会有所不同? [英] Why does this code behave differently if optimizing (-O2, -O3) is used?

查看:277
本文介绍了如果使用优化(-O2,-O3),为什么此代码的行为会有所不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I had to code some checking routines and they appear to behave differently if one uses -O0, -O1, -O2 or -O3.

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

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.

#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?

尝试使用gcc,clang和icc时,只有icc可以在所有优化变体中都对它进行校正,而其他两个则不能.

Trying with gcc, clang and icc, only the icc does it correct in all optimization variants the other two did not.

推荐答案

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

这篇关于如果使用优化(-O2,-O3),为什么此代码的行为会有所不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆