我是靠谱客的博主 英俊砖头,最近开发中收集的这篇文章主要介绍【Chapter10*编程总结*】解决multiple definition of `err_ret'问题以及文件包含、条件编译,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

写在前面
一步一个知识点解决,稳扎稳打。搞清楚,弄明白,多动脑,脑子越不用越废,越废越不用,恶性循环~

一、问题产生

在实现父子进程同步时,我自己写的一个tell_wait.c文件,头文件是tell_wait.h文件,里面包含了apue.h,而主程序10-6.c中也包含了apue.h,两个文件联合编译时gcc 10-6.c tell_wait.c -o 10-6,则出现以下问题:

/tmp/ccOYTi4X.o: In function `err_ret':
sync.c:(.text+0x0): multiple definition of `err_ret'

这是因为在多个文件中包含相同的头文件,编译时分别编译为两个.o文件,而在链接的时候,会产生多定义的错误。

既然系统提示错误为err_ret函数有重定义,那不妨找一下err_ret函数在哪个文件,又是如何与apue.h关联的?实际上,在apue.h里面,通过#include"error.c"将error.c文件包含进来,那两个文件在引用apue.h时,也就是引用了error.c,所以造成重定义。上图:
在这里插入图片描述

二、解决包含.c文件的方案

2.1 包含.c文件和多文件编译

从上看出,包含文件有两种:.c文件和.h文件。

包含.c文件:把函数的定义复制进来,很容易多个文件引用同一.c文件时,产生重定义。
包含.h文件:把函数声明复制到本文件中,而主文件与.h对应的.c文件进行多文件编译,实际编译时每一个.h文件中声明的函数在.c中只对应一个,因此不会产生重定义。

因此推荐使用包含.h文件的方法。针对一,可以创建error.h文件,使apue.h包含error.h文件,但在编译时需要编译error.c。上图:
在这里插入图片描述
那不禁要问了,每次都要把error.c文件复制到工程下,在编译的时候多文件。如果是多个工程,不是要做许多重复性工作吗?对的,每写一个都要复制相同的error.c文件,确实很麻烦。有没有什么办法能够解决呢?环境变量的妙用~

2.2 .bashrc的妙处

.bashrc可设置函数和环境变量。可以是系统级的,也可以是用户级的。
系统级的.bashrc位于/etc/bash.bashrc位置:

fairy@ubuntu:/etc$ vim bash.bashrc 

用户级的.bashrc文件位于/home/用户名/.bashrc:

fairy@ubuntu:/etc$ cd /home/fairy/
fairy@ubuntu:~$ vim .bashrc

一般更改用户级的环境变量就满足了。在.bashrc最后面添加一行:
环境变量名=路径 这里取apue_error作为变量名,路径是error.c的位置。

#Unix编程中,给apue.h添加error.c环境变量
 apue_error=/home/fairy/Unix_Code/src.3e/apue.3e/lib/error.c   

保存后,需执行source命令,重新读取.bashrc,保证修改立即生效:

fairy@ubuntu:~$ source .bashrc

查看apue_error,看是否设置成功

fairy@ubuntu:~$ echo ${apue_error}
/home/fairy/Unix_Code/src.3e/apue.3e/lib/error.c

OK!搞定!运行时只需多编译${apue_error}即可,示例如下。

fairy@ubuntu:~/Unix_Code/Chapter9$ gcc 10-6.c sync.c ${apue_error} -o 10-6.out

三、条件编译

既然二中提到包含.h文件就可以解决多定义的问题,为何又时常见到下面的语句:

#ifndef _APUE_H_
#define _APUE_H_
#include"apue.h"
#endif

毫无疑问,这是条件编译。它是在什么问题下使用的呢?使用.h文件包含能否解决这个问题?
参见文章:编程易忽略细节一:文件包含使用条件编译解决多定义错误

四、参考链接

(1)更改Unix中apue多定义错误
https://www.cnblogs.com/yhLinux/p/4079930.html
(2)文件包含.c和.h的区别
https://blog.csdn.net/doniexun/article/details/38324933
(3)profile、bash_profile、bashrc文件的作用与区别
https://itbilu.com/linux/management/NyI9cjipl.html

最后

以上就是英俊砖头为你收集整理的【Chapter10*编程总结*】解决multiple definition of `err_ret'问题以及文件包含、条件编译的全部内容,希望文章能够帮你解决【Chapter10*编程总结*】解决multiple definition of `err_ret'问题以及文件包含、条件编译所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部