Visual Studio C++编译器优化打破代码?

Sto*_*sen 2 c++ compiler-optimization visual-studio visual-c++

我在这里遇到了一个奇怪的问题,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
}
Run Code Online (Sandbox Code Playgroud)

然后是另一个函数的循环:

for (int i = 0; i < 11; ++i)
{
  double b = f(i * 10);
}
Run Code Online (Sandbox Code Playgroud)

现在发生的事情是,在调试构建中一切正常.在发布所有优化的发布版本中,这是根据反汇编编译的,因此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;
}
Run Code Online (Sandbox Code Playgroud)

我在我的机器上用VS2010测试了这个,它看起来像我遇到问题的原始代码一样糟糕.我在发布配置中使用IDE的默认空C++项目模板编译并运行它.如你所见,永远不应该打破休息(37*16 = 592).请注意,删除i < 4使其工作,就像在原始代码中一样.

Sto*_*sen 6

对于任何感兴趣的人,它都是VS编译器中的一个错误.由Microsoft确认并在报告后的服务包中修复.