该死的c语言的隐式函数声明法则


在a.c文件里c函数的原型为:
char* function();

在另外的b.c文件里没有引用a.c对应的头文件,即没有function的函数原型声明,直接调用此上面的c函数:
char* ret = function();

编译没有什么问题,但是run的时候就发现程序在上述调用的位置crash掉了。用gdb跟踪发现调用后ret的值如下:
$2 = 0xfffffffff7fcf6f8 <Address 0xfffffffff7fcf6f8 out of bounds>

即function()函数返回的地址为非法的地址,而跟踪到function函数里面可知,它返回的值是一个类似于0xfffff7fcf6f8这样的合法值的。
为什么一到function函数的外面就是变成了0xfffffffff7fcf6f8这样的非法值呢?而且这个地址是在function内部的返回值0xfffff7fcf6f8的基础上补了两个全f字节,即不全了八个字节。

调试了一天也没有发现什么原因,这么稀奇的错误以前还真是从来没有碰到过,急死了!最后google了一下,有人提议碰到这种crash的问题,可以加-Wall来看下warning信息,crash出应该有对应的warning信息。于是乎,修改Makefile,加上警告信息。果然发现了warning信息,warning: assignment makes pointer from integer without a cast。

再根据此warning信息google了一把,发现然来c语言里面,使用之前没有声明的函数编译器都认为是隐式声明的函数,编译器会将所有隐式声明的函数的返回值类型都认定为int。然来问题在这里啊,对c语言用的不多,确实不知道还有这么一神奇的规则呀!function()返回的地址被编译器强制转换成int类型了,而64位OS上int为8个字接,所以function内部的返回值0xfffff7fcf6f8被补了两个全f字节变成了8个字节,故地址越界了。

从C99开始,废除了这条隐式函数声明法则,它会给出与c99之前版本不同的warning: implicit declaration of function。

所以呀,在c语言里面开来还是要学习c++的编程习惯,使用函数之前一定要声明。不然,即使编译能通过,运行时也可能会出一些莫名其妙的问题。
  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值