今天发现了一个C里容易忽略的细节。
由于这个小细节,我的程序调试了半天,耽误了不少功夫。
现在拿出来和大家分享一下~共同进步~。
首先,VC下的,一个很简单的程序
# include <stdio.h>
int main ()
{
short int a ;
a = 0x8000 ;
if (a == 0x8000)
printf ("T\n") ;
else
printf ("F\n") ;
return 0 ;
}
大家猜才结果是什么呢?
答案是F。
如果你认为是T,呵呵,最好自己调试一下,找到原因,不太难的,找不到的话再往下看~~
(如果你认为本来就是F,理由是short int 的范围是-32768到32767,这里0x8000是32768,溢出了,不相等,那么,不好意思,你的理解有偏差。不信你把short int换成int,再把0x8000扩展到0x80000000,同样的问题在int型的时候输出T,怎么解释?~)
这里,a是short int型,占两个字节。当我们把0x8000赋给a后,a中的值为
1000 0000 0000 0000(二进制)
在执行if条件时,程序要把a的值和立即数0x8000进行比较。
但是a的值保存在内存当中,于是程序会将a的值从内存里取到寄存器中(通常是eax)
mov eax, a的地址 ; 这个是假想生成的代码
但是a的值只有2字节,eax有4字节。这里编译器在取的时候做了一个符号扩展:
movsx eax, a的地址 ; 这个是实际生成的代码
这样,编译器其实是拿eax里,也就是a的值符号扩展后,也就是0xffff8000和0x8000进行比较,判定为不相等。
现在,如果把short int 换成int,0x8000换成0x80000000就不会出现判断失误的问题了。因为int和eax是等长的,没有进行符号扩展。
分析完毕。请各位高手拍砖留情~
- 标 题:一个C里容易忽略的细节
- 作 者:冬祭
- 时 间:2009-08-11 20:21
- 链 接:http://bbs.pediy.com/showthread.php?t=95528