我在这里有一个特殊的问题,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
使这项工作,就像在原始代码中一样。