我这里有一个特殊的问题,这在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/