可能的VS2012编译器错误(可能在整个程序优化中?)

时间:2013-08-04 23:36:43

标签: c++ visual-studio-2012 compiler-optimization compiler-bug

这可能是编译错误吗?我的环境是:

  • Win7 pro(64位)
  • VS2012(更新3)

我编译下面的小控制台程序。对于x64位发布/调试版本,一切正常。 x32调试版本也可以正常工作。然而,x32版本构建显示“BUG!”。

如果我禁用“整个程序优化”来解决问题。

有什么想法吗?

-

#include <string>
#include <iostream>


int main()
{
    std::string const buffer = "hello, world";
    std::string::size_type pos = 0;
    std::string::size_type previous_pos;


    while (pos != std::string::npos)
    {
        previous_pos = ++pos;
        pos = buffer.find('w', pos);
    } 


    if (previous_pos == std::string::npos)
    {
        std::cout << "BUG!!"<< std::endl;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:4)

我也可以重现这一点。当bug出现时,代码正在测试eax,以确定是否输出“BUG”,这与'pos'使用的寄存器相同。

17:         previous_pos = ++pos;

013C12E5 inc eax
...

21:     if (previous_pos == std::string::npos)

00301345 cmp eax,eax
00301347 jne main + 0F6h(0301366h)

但是,如果您进行更改以尝试让优化器意识到它们是不同的,则测试会有所不同。如果我在循环体的末尾添加++ previous_pos,那么它使用ecx for previous_pos并且bug消失了:

22:     if (previous_pos == std::string::npos)

00361349 cmp ecx,eax
0036134B jne main + 0FAh(036136Ah)

如果我将find更改为'pos = buffer.find('w',previous_pos);' (从previous_pos搜索而不是pos,它具有相同的值)然后它使用ebx,并且bug再次消失:

21:     if (previous_pos == std::string::npos)

00191345 cmp ebx,eax
00191347 jne main + 0F6h(0191366h)

原来似乎优化器错误地决定它可以对这两个变量使用eax,尽管行'pos = buffer.find('w',pos);'可以将pos设置为与previous_pos不同的值。