| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 600 人关注过本帖
标题:这算是VC6.0编译器的一个Bug么?
只看楼主 加入收藏
symanli
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-4-5
结帖率:0
收藏
 问题点数:0 回复次数:2 
这算是VC6.0编译器的一个Bug么?

今天在VC6.0写下如下代码:
view plaincopy to clipboardprint?
#include

int bug()
{
int a=3,b;
b=(++a)+(++a)+(++a);
return b;
}

void main()
{
int b = bug();
printf("%d", b);
view plaincopy to clipboardprint?
#include

int bug()
{
int a=3,b;
b=(++a)+(++a)+(++a);
return b;
}

void main()
{
int b = bug();
printf("%d", b);
}
#include

int bug()
{
int a=3,b;
b=(++a)+(++a)+(++a);
return b;
}

void main()
{
int b = bug();
printf("%d", b);
}


首先看看我上面这段C代码,按照C语言的运算符优先级规则,这个程序的运行结果应该是18(首先执行完小括号里的三个++a,这时a就为6,然后在执行加法运算,3个a相加自然等于18)。

可是我在VC6.0下编译这段程序时,如果编译为Debug版,则输出结果为16,如果编译为Release版本,则输出结果为18。

为什么Debug版本的结果会是16呢???怎么想也不应该是16啊。于是自然就想到了看看这段程序对应Debug版的汇编代码吧,看看VC的编译器究竟把这段代码编译成什么样子了。为了简单起见,我只分析子函数bug()。

int a=3,b;
b=(++a)+(++a)+(++a);

以上这两行代码在VC的Debug版本下对应的汇编代码为:
0040102F 8B 45 FC mov eax,dword ptr [ebp-4]
00401032 83 C0 01 add eax,1
00401035 89 45 FC mov dword ptr [ebp-4],eax
00401038 8B 4D FC mov ecx,dword ptr [ebp-4]
0040103B 83 C1 01 add ecx,1
0040103E 89 4D FC mov dword ptr [ebp-4],ecx
00401041 8B 55 FC mov edx,dword ptr [ebp-4]
00401044 03 55 FC add edx,dword ptr [ebp-4]
00401047 8B 45 FC mov eax,dword ptr [ebp-4]
0040104A 83 C0 01 add eax,1
0040104D 89 45 FC mov dword ptr [ebp-4],eax
00401050 03 55 FC add edx,dword ptr [ebp-4]
00401053 89 55 F8 mov dword ptr [ebp-8],edx

上面这段汇编代码的意思,相信只要懂得汇编的朋友都可以很容易看懂,不过为了照顾一下大众,我还是简单说明一下吧,根据变量定义的位置可以知道,ebp-4就是变量a的地址,ebp-8就是变量b的地址,于是以上代码可以简化为:
mov eax,a
add eax,1
mov a,eax
//此时a=4
mov ecx,a
add ecx,1
mov a,ecx
//此时a=5
mov edx,a
add edx,a
//此时edx=10
mov eax,a
add eax,1
mov a,eax
//此时a=6
add edx,a
mov b,edx
//此时b=16

所以,最后的结果当然就是16啦。

随后我又用OD对Release版的程序进行了逆向分析,大家看图:
图片附件: 游客没有浏览图片的权限,请 登录注册





这个结果让我感到很意外,在Release版中,子函数bug()居然被优化成了直接返回结果:0x12(十进制就是18)。

至于其中为什么会优化成那样的原因我可就不知道了,这要去问问微软那些开发这个VC编译器(这里顺便一下:VC6.0自带的 C/C++编译器版本为:Version 12.00.8804)的工程师了,呵呵。当然也可以通过逆向分析这个VC编译器,从而找到答案,不过本人能力有限,目前还很难办到,若哪位大牛路过本站,还请不吝赐教,我的站点是www.。请大家来帮忙解决啊?????
搜索更多相关主题的帖子: Bug 编译 
2010-06-15 20:16
lvan100
Rank: 2
等 级:论坛游民
帖 子:6
专家分:40
注 册:2010-6-16
收藏
得分:0 
貌似这么运算的时候为未定义形式,就是说结果是什么根据编译器而定,国际标准中没有规定执行顺序该怎么做。所以,尽量不要出现这样的运算。可以查查c语言的国际标准。
2010-06-16 22:54
迷失的木桶
Rank: 4
等 级:业余侠客
帖 子:52
专家分:230
注 册:2010-5-29
收藏
得分:0 
楼上正解,这的确是未定义行为。
2010-06-17 07:59
快速回复:这算是VC6.0编译器的一个Bug么?
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015526 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved