Visual C++ 2008 的错误?

11

非常简单的代码(在MS Visual C++ 2008 Express下):

#include <iostream>
using namespace std;

int main()
{
    for (int a=1; 2*a<=7; a++)
        cout << a << endl;
    return 0;
}

调试模式给我了 正确 的结果:

1
2
3

然而发布模式却给我带来了错误的结果:

1
2

好的,我理解可能的答案是“使用2*a<8”、“为什么不是a<=3”、“a<4”。

我不想改变代码,因为它是正确的代码(在调试模式下运行良好,所有变量都被很好地初始化等)。

  • 你在 Visual C++ 2008 Express 中是否有相同的 bug?
  • 在更新版本(2010、2012)中是否存在此 bug?
  • 如何避免此 bug?
  • 有没有修复它的 SP?
  • 也许更改一些编译选项(而不是默认选项)可以解决问题?

更新:

当我写下

cout << a+1 << endl;
或者
cout << 2*a << endl;

它正常工作/编译正确(3行输出)。


注意:我在不同的计算机上尝试了VC++2008 Express。行为相同。


2
将输出重定向到文件,并确保它实际上是不正确的,而不是在查看输出的任何内容中存在显示/缓冲问题。 - Mat
@Mat,在调试器下我看到了"mov esi, 1" 然后将esi与2进行比较。我认为这不是输出问题。 - Oleg567
2
这种行为在我的VC 2013中没有出现,无论是在调试模式还是发布模式下。 - Xiangyan Sun
3
@Mat 这不是一个简单的循环,你是否曾经需要编写这种代码?在发布VC 2012之前,存在多个与for循环相关的优化错误。http://blogs.msdn.com/b/vcblog/archive/2012/08/10/10338661.aspx(搜索“loop”) - Xiangyan Sun
2
在2012年和2013年的優化版本中正常運作。我說這是個錯誤,但微軟不會急於修復它。 - defube
显示剩余12条评论
1个回答

7
我可以在VS2008 SP1上重现这个问题。像往常一样,这是一个代码优化器的bug。你需要查看反汇编代码以查看原因。当它因式分解时,它会在“2*a <= 7”处出错,它会生成"a <= 2"的代码。当然是错误的,应该是"a <= 3"或"a < 4"。看起来它没有正确处理<=操作符的除法。有点棘手,它必须知道奇数和偶数之间的区别 :)
如果你不让它强制计算出用除法如何处理<=,使用“2*a < 8”就能正常工作,这个bug就会消失。
这个bug已经在一段时间前被修复了,由于旧版本的错误报告已经从公共网站中删除,所以我不知道确切的时间。处理优化器错误的最佳方法是给他们一个修复的机会,保持编译器更新非常重要。你有三个较新版本的Express版可供选择,在编译器开发中相当于两个狗的生命周期。有了C++11,就有三种选择 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接