|
|

楼主 |
发表于 2005-6-14 20:17:00
|
显示全部楼层
Re:发现VC++ 6.0的BUG,很有趣
如果是滥出,为什么程序不出错,只是死循环.再说了,代码中哪里有滥出的机会?
最有力的说明是反汇编代码401000: jmp 400100,这一行代码就足以说明了这一点.上面代码要用release的fast优化编译方式,而不能用debug的常规编译方式,因为debug不进行代码优化,所以自然不会出现优化错误.
为什么会产生这种情况,我想是优化造成的,有点反汇编基础的人都知道,没有任何代码的空循环是不会被编译的,而会被忽略,被赋一次值就没再改变的变量(上面代码中的ret = FALSE;return ret),是会直接return FALSE代替的.
BOOL Test()
{
BOOL ret = FALSE;
for(unsigned long i = 1; i >= 0; --i)
{
}
return ret;
}
编译器第一步优化:判断循环没有任何用处,可以忽略编译.
编译器第二步优化:判断ret没有任何改变值的机会,用return FALSE代替.
编译器第三步优化:判断ret和i在函数返回前的最终值一定相等,都等于0.所以用同一个寄存器来表示两个变量
所以到第三步优化时,已经出现优化絮乱,代码成了:
BOOL Test()
{
register BOOL ret = FALSE;
unsigned int &i = ret;
for(;i>=0;)
{
}
return FALSE;
}
}
再经过第四步优化,判断该函数是个死循环.所以直接用jmp xxxx跳回本位代码代替.
优化错误,但优化得相当厉害,jmp xxxx一行代码就代替了以下所有的代码:
BOOL Test()
{
BOOL ret = FALSE;
for(unsigned long i = 1; i >= 0; --i)
{
}
return ret;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
Test();
return 0;
} |
|