免费注册 查看新帖 |

Chinaunix

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

[C] APUE中程序8_4编译时的multiple definition问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-14 12:38 |只看该作者 |倒序浏览

在学APUE,看到第八章,程序清单8_4中的程序需要调用8_3中定义的函数void pr_exit(int status),于是我把这两个.c文件放在同一个文件夹下,然后用命令 cc -o a.out pr_exit.c exitstatus.c 对其进行编译,但编译报错: multiple definition of 'err_sys(char const*, ...)'  同样其他几个错误处理函数也是多重定义的问题。

我在写APUE程序时对apue.h和error.c的处理方式是把apue.h和error.c放在usr/include/文件夹下,并在apue.h中最后一行#endif前面添加了#include <error.c>  后来又在error.c文件首尾添加了
#ifndef ERROR_C
#define ERROR_C
...
#endif(此句在文件尾)

后来我换了一种方式,逐步编译,先作编译预处理,再编译,再汇编,生成了两个.o文件后最后再用 cc -o a.out pr_exit.o exitstatus.o 进行编译,还是报和上面一样的错误。

之前编译程序的时候都是单文件的源程序,是没有问题的。但这次是两个.c文件一起编译,就出现了多重定义的问题,求各位帮忙啊~ 多谢了~!

论坛徽章:
12
巳蛇
日期:2013-09-16 15:32:242015年辞旧岁徽章
日期:2015-03-03 16:54:152015年亚洲杯之约旦
日期:2015-02-11 14:38:37双鱼座
日期:2015-01-05 11:05:47戌狗
日期:2014-12-08 09:41:18戌狗
日期:2014-08-15 09:29:29双子座
日期:2014-08-05 09:17:17卯兔
日期:2014-06-08 15:32:18巳蛇
日期:2014-01-27 08:47:08白羊座
日期:2013-11-28 21:04:15巨蟹座
日期:2013-11-13 21:58:012015年亚洲杯之科威特
日期:2015-04-17 16:51:51
2 [报告]
发表于 2013-11-14 15:27 |只看该作者
假设有1.c和2.c两个文件,函数a定义在a.c中,然后1.c和2.c分别包含a.c,那么:

编译1.c的时候,a.c被展开到1.c中,最后1.o中包含a的定义;
编译2.c的时候,发生了同样的事,所以2.o中也包含a的定义。

结果就是1.o和2.o都包含a的定义,链接的时候就会报多重定义的错。

所以,正确的做法是:
1.不要include一个.c文件,除非你真的弄明白了你到底要干嘛,并且认为必须/有足够理由这么做。
2.不要在头文件中定义全局变量或者函数,头文件中应该只是声明变量和函数。例外情况是当
你想确保一个函数被inline时,可以在头文件中把它定义为static inline的。

ifndef这种阻止多重包含的方法仅仅针对一个编译单元,它能确保的是同一个头文件不会在一个编译单元内展开两次,对于多个编译单元的多重定义问题没有帮助。

论坛徽章:
0
3 [报告]
发表于 2013-11-14 21:04 |只看该作者
zhaohongjian000 发表于 2013-11-14 15:27
假设有1.c和2.c两个文件,函数a定义在a.c中,然后1.c和2.c分别包含a.c,那么:

编译1.c的时候,a.c被展开 ...


多谢多谢!!!我把apue.h中自己加的那行#include<error.c>删掉了,在编译的时候加上了error.c的目录,成功生成了可执行文件!
原来以前对使用宏避免多重包含的理解还是很肤浅啊,以为加上#ifndef后就完全没有问题了。在了解了编译过程之后才明白原来只能避免一个编译单元内的多重包含!

后来我也是没想清楚如果需要使用inline函数该怎么办,原来用static inline就可以解决,是这样啊,太感谢了!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP