在gcc中,函数不需要先声明,而g++需要

有一个问题:在64位系统中,有一个c文件中的一个函数函数声明是返回void*的,但是由于使用之前没有声明,导致函数返回值默认为int,指针被强制转为32位整数,出错。

参考知乎:在C语言中,函数调用前是否必须先声明?https://www.zhihu.com/question/35890756

接下来只要看这个问题的高票回答即可:
Implicit function declarations in C
It should be considered an error. But C is an ancient language, so it's only a warning.
Compiling with -Werror (gcc) fixes this problem.

When C doesn't find a declaration, it assumes this implicit declaration: int f();,
 which means the function can receive whatever you give it, and returns an integer.
 If this happens to be close enough (and in case of printf, it is), then things can work.
 In some cases (e.g. the function actually returns a pointer, and pointers are larger than ints), it may cause real trouble.
Note that this was fixed in newer C standards (C99, C11). In these standards, this is an error. However, gcc doesn't implement these standards by default, so you still get the warning.

(大家似乎打不开那个链接所以把主要内容复制了过来。)
GCC只是默认还允许implicit function declaration功能而已,较新的C规范(C99、C11)是不允许不声明直接用的。
================================================================================================================================
在C语言老的规范中,函数没有声明也可以使用(宏定义和变量必须声明),只是说没有显式声明。新的规范不允许,但是gcc为了兼容老代码,只是有告警。
在这个例子中,osa_alloc被编译器认为原型是 int fun();在osa_alloc函数内申请了正确的64位指针 0x7ffff7f5a010 后,在返回值时,编译器将后32位截断,
并返回了一个32位的int,0xf7f5a010。在mux_mallocMem函数又返回void* 时,编译器又将32位的int转换为64位的指针,在它之前添加了 0xffffffff。因此,mux_mallocMem返回了0xfffffffff7f5a010这个错误的地址。
可以看出,如果在32位的系统上,因为指针是32位的,在上述的  指针->整数->指针 的转换中,并不会出错。
========================================================================================================================
记得C语言并不强行要求函数在使用前先声明
如果你在代码中写了一个未声明的函数,那么编译器编译到这里时会假设这个函数的参数列表就是你使用它的这些参数类型,而返回值为int型
如果之后的编译链接中发现这个函数的真正定义并不是编译器假设的那样,再报错
调用函数只是把参数压栈然后跳转,并不需要知道函数的具体功能,只要参数列表返回值和调用约定确定了,编译就没有问题

以上是模糊记得,可能错,毕竟没怎么深入研究过C语言,仅供参考


posted @ 2017-11-29 21:53  elseliving的记录  阅读(602)  评论(0编辑  收藏  举报