免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2300 | 回复: 7
打印 上一主题 下一主题

[C] GCC有没有外部类型检查功能? [复制链接]

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-06-10 17:34 |只看该作者 |倒序浏览
首先描述一个实验现象。

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里有没有什么功能开关来支持类似的类型检查和代码分析呢?

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:032015年亚洲杯之中国
日期:2015-04-22 15:52:45
2 [报告]
发表于 2013-06-10 21:31 |只看该作者
真能编译通过? 不会报LINK找不到引用函数的错误么--

论坛徽章:
0
3 [报告]
发表于 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个文件:
  1. /* main.c */
  2. int foo(int arg1 )__attribute__((weak));
  3. int foo(int arg1)
  4. {
  5.         printf("foo in mian.c\n");
  6.         return 0;
  7. }
  8. int main(void)
  9. {
  10.         foo(1);
  11.         return 0;
  12. }
复制代码
  1. /* func.c */
  2. int foo(int arg1,int arg2)__attribute__((weak));
  3. int foo(int arg1,int arg2)
  4. {
  5.         printf("foo in func.c\n");
  6.         return 0;
  7. }
复制代码

编译:
  1. gcc main.c func.c -o main1
  2. gcc func.c main.c -o main2
复制代码

运行:
  1. [fly][zodiac1111@fc tmp]$ ./main1
  2. foo in mian.c
  3. [zodiac1111@fc tmp]$ ./main2
  4. foo in func.c[/fly]
复制代码

-- update --
更新基础知识错误

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
4 [报告]
发表于 2013-06-11 20:08 |只看该作者
非常感谢!!
这些关键词给了我很多信息!

另外attribute(weak)让我想起了Linux内核中的一些实例。再次感谢!
回复 3# zodiac1111


   

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
5 [报告]
发表于 2013-06-11 20:41 |只看该作者
回复 3# zodiac1111

嗯,看了强符号与弱符号相关知识,发现和我这个问题不是同一个问题。

我这个例子中main.c中的func应该既不是弱符号也不是强符号哦。

对于我这个问题,你说的很对,用头文件来统一函数声明肯定是最佳解决方法,而且一般都会这么做。我只是好奇一旦由于人为的原因出现这种“错误”,GCC有没有基于多个编译单元检查一致性的功能。


   

论坛徽章:
0
6 [报告]
发表于 2013-06-11 23:22 |只看该作者
回复 5# bensenq


    main.c中这个func不是弱符号吗?我也只有查到
在本目标文件中定义的函数和初始化了的全局变量为强符号,本目标文件中定义的未初始化全局变量为弱符号,而在本目标文件中使用extern引用的符号不属于强弱符号定义的范畴。

http://blog.21ic.com/user1/7747/archives/2010/77582.html

这里似乎属于隐含的extern?是吗?记得哪里看到过全局的函数/变量默认extern,能找到官方提及的这部分知识吗?

论坛徽章:
4
白羊座
日期:2013-09-17 21:59:30技术图书徽章
日期:2013-10-12 22:16:03白羊座
日期:2013-10-14 11:01:40双子座
日期:2013-12-17 18:26:39
7 [报告]
发表于 2013-06-12 19:46 |只看该作者
这应当与强符号和弱符号无关,而与函数名称修饰有关。
对于c语言,编译器产生的最终名称,是不包含函数的参数的信息的。所以,int function(int arg1, int arg2)和int function(int arg1)产生的名称相同。在链接时,所以没有问题。
如果换为c++就会检查出这种错误,因为c++是包含参数的信息的。

论坛徽章:
1
水瓶座
日期:2013-09-28 21:40:25
8 [报告]
发表于 2013-06-13 12:44 |只看该作者
非常感谢!
回复 7# 井蛙夏虫


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP