gcc的一个小bug

    在C语言里有一个通用指针,即void*类型指针。通用指针有一条特殊的性质:任何一个指向某种类型(非函数类型)数据的指针转型为通用指针后再转换回原始类型,指针(的值)不会改变。换句话说,任何非函数类型的指针与通用指针间的互相转型(以及赋值)是(语法上)合法且(语义上)安全的。

    通用型指针实际是一种类型未知的指针,因此不能对它解引用(dereference)和施行下标(subscripting)操作,也不能把它加加减减。

    根据以上描述,下面这段程序

/* fool.c */
void foo(void *p)
{
   ++p;
}

显然就是非法的。

    可是作者在Win2000平台上用gcc -S fool.c(MinGW 3.1.0,其中gcc为3.2.3版本)却顺利编译通过了上述代码,生成的汇编码如下:

_foo:
   pushl %ebp
   movl  %esp, %ebp
   incl  8(%ebp)
   popl  %ebp
   ret

注意incl  8(%ebp)这条指令,显然gcc把void*指针当成了char*指针,并对它施行了相应的自增操作(前进一个byte)。真是自作聪明!

    大家不要误以为这是gcc为了兼容老程序而有意为之,实际上史前的C根本没有void*型指针,也就不存在所谓兼容问题了。编译器这种不声不响的小动作不太惹人注意,但危险可是大大的,程序员千万要保持警惕!

    试试VC6.0,用cl /c fool.c编译,会得到一个"error C2036: 'void *' : unknown size"的错误信息。嗯,这才对头!

    这一次Visual C++的表现好于gcc,值得表扬。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值