Chinaunix
标题:
GCC有没有外部类型检查功能?
[打印本页]
作者:
bensenq
时间:
2013-06-10 17:34
标题:
GCC有没有外部类型检查功能?
首先描述一个实验现象。
1. func.c里面定义实现一个函数,int function(int arg1, int arg2);
2. main.c里面实现了main函数,并以int function(int arg1)方式声明和调用了function(少用了一个参数)。
3. 这样通过命令gcc func.c main.c -o main能够编译通过,不会报错。
看了些文章,自己也做了些实验,发现主要是由于类型检查都是基于一个编译单元(即一个源文件),而在链接时又无法获得相关类型的信息,所以就没法进行外部类型检查。
貌似Lint工具能够进行相关静态代码分析,想知道GCC里有没有什么功能开关来支持类似的类型检查和代码分析呢?
作者:
hanxin83
时间:
2013-06-10 21:31
真能编译通过? 不会报LINK找不到引用函数的错误么--
作者:
zodiac1111
时间:
2013-06-11 14:58
本帖最后由 zodiac1111 于 2013-06-11 23:26 编辑
以下皆为
有限的水平
下的
个人见解
,不提供任何担保.
简而言之
:使用
头文件
分离声明和实现可以有效避免这种"错误"的发生.
这种情况,
* main中的foo函数只有声明没有实现,是一个
<del>弱符号</del>
.(update:这是错误的,概念范畴不同).
* func.c中的foo函数是一个
强符号
.
即使两者声明的形式完全一致,如都声明为 int function(int arg1, int arg2),
那么也是调用func.c中的函数(强符号). [也可能是gcc(c语言)编译器生成的符号没有包含参数列表的标志,所以形成了同名的符号,g++不知道什么情况]
同个程序可以有0个至多个弱符号,但不能有多与一个的(同名)强符号.不然就会ld就会抱怨"重复定义blabla.."
而若有
多个
弱符号
没有
强符号,则跟链接(link)的顺序有关.先到先得[测试1].
# 关键词:
强符号,弱符号.weak symbol
# 参考:
*
http://www.trueeyu.com/?p=855
*
http://en.wikipedia.org/wiki/Weak_symbol
*
http://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html
weak
# 测试1(弱符号的调用顺序):
如下2个文件:
/* main.c */
int foo(int arg1 )__attribute__((weak));
int foo(int arg1)
{
printf("foo in mian.c\n");
return 0;
}
int main(void)
{
foo(1);
return 0;
}
复制代码
/* func.c */
int foo(int arg1,int arg2)__attribute__((weak));
int foo(int arg1,int arg2)
{
printf("foo in func.c\n");
return 0;
}
复制代码
编译:
gcc main.c func.c -o main1
gcc func.c main.c -o main2
复制代码
运行:
[fly][zodiac1111@fc tmp]$ ./main1
foo in mian.c
[zodiac1111@fc tmp]$ ./main2
foo in func.c[/fly]
复制代码
-- update --
更新基础知识错误
作者:
bensenq
时间:
2013-06-11 20:08
非常感谢!!
这些关键词给了我很多信息!
另外attribute(weak)让我想起了Linux内核中的一些实例。再次感谢!
回复
3#
zodiac1111
作者:
bensenq
时间:
2013-06-11 20:41
回复
3#
zodiac1111
嗯,看了强符号与弱符号相关知识,发现和我这个问题不是同一个问题。
我这个例子中main.c中的func应该既不是弱符号也不是强符号哦。
对于我这个问题,你说的很对,用头文件来统一函数声明肯定是最佳解决方法,而且一般都会这么做。我只是好奇一旦由于人为的原因出现这种“错误”,GCC有没有基于多个编译单元检查一致性的功能。
作者:
zodiac1111
时间:
2013-06-11 23:22
回复
5#
bensenq
main.c中这个func不是弱符号吗?我也只有查到
在本目标文件中
定义的函数
和初始化了的全局变量为强符号,本目标文件中定义的未初始化全局变量为弱符号,而在本目标文件中
使用extern引用
的符号不属于强弱符号定义的范畴。
http://blog.21ic.com/user1/7747/archives/2010/77582.html
这里似乎属于隐含的extern?是吗?记得哪里看到过全局的函数/变量默认extern,能找到官方提及的这部分知识吗?
作者:
井蛙夏虫
时间:
2013-06-12 19:46
这应当与强符号和弱符号无关,而与函数名称修饰有关。
对于c语言,编译器产生的最终名称,是不包含函数的参数的信息的。所以,int function(int arg1, int arg2)和int function(int arg1)产生的名称相同。在链接时,所以没有问题。
如果换为c++就会检查出这种错误,因为c++是包含参数的信息的。
作者:
bensenq
时间:
2013-06-13 12:44
非常感谢!
回复
7#
井蛙夏虫
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2