我这里有一个特殊的问题,这在VS2005和2010上都发生。我有一个for循环,其中调用了内联函数,本质上是这样的(C++,仅出于说明目的):

inline double f(int a)
{
  if (a > 100)
  {
    // This is an error condition that shouldn't happen..
  }

  // Do something with a and return a double
}

然后在另一个函数中循环:
for (int i = 0; i < 11; ++i)
{
  double b = f(i * 10);
}

现在发生的事情是在调试版本中一切正常。根据反汇编,在发布版本中启用了所有优化功能的情况下,将对它进行编译,以便直接使用i而不使用* 10,并且比较a > 100变成a > 9,而我猜应该是a > 10。关于导致编译器认为a > 9是正确方法的问题,您有什么建议?有趣的是,即使对周围的代码进行很小的更改(例如调试打印输出),编译器也会使用i * 10并将其与文字值100进行比较。

我知道这有些含糊,但是我对任何旧的想法都会感激不尽。

编辑:

这是一个有望重现的案例。我认为它不会太大,不能粘贴到这里,所以去了:
__forceinline int get(int i)
{
  if (i > 600)
    __asm int 3;

  return i * 2;
}

int main()
{
  for (int i = 0; i < 38; ++i)
  {
    int j = (i < 4) ? 0 : get(i * 16);
  }

  return 0;
}

我在计算机上使用VS2010进行了测试,它的表现和我遇到问题的原始代码一样糟糕。我在发行版配置中使用IDE的默认空C++项目模板进行了编译和运行。如您所见,该中断永远不会被击中(37 * 16 = 592)。请注意,删除i < 4可以完成此工作,就像原始代码中一样。

最佳答案

对于任何有兴趣的人来说,事实证明这是VS编译器中的错误。由Microsoft确认,并在报告后的Service Pack中修复。

关于c++ - Visual Studio C++编译器优化会破坏代码吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3724905/

10-12 12:43
查看更多