这可能是编译错误吗?我的环境是:
我编译下面的小控制台程序。对于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;
}
答案 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不同的值。