【发布时间】:2011-04-13 02:23:43
【问题描述】:
我在这里遇到了一个特殊的问题,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,而我猜它应该是@987654327 @。你有什么线索可以让编译器认为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 会使其正常工作,就像在原始代码中一样。
【问题讨论】:
-
提供一个可编译并重现问题的最小示例怎么样?
-
您写道,为优化构建生成的汇编语言不是您所期望的。但并不完全清楚优化后的程序执行不正确。您能否确认确实如此,并告诉我们这两个版本的不同结果是什么?
-
实际上,在提出这个问题之前,我自己很快就尝试将其作为一个完全独立的案例重现,但到目前为止还没有以相同的方式编译它。我无法复制粘贴原始代码,但我会看看能否获得问题部分的独立非上下文版本。
标签: c++ visual-studio visual-c++ compiler-optimization