大家好,欢迎来到IT知识分享网。
重定义是什么
重定义就是定义了多次 一般解决重定义的方法是用宏指令 ifndef endif .但是这个方法只能解决重复包含同一个文件的问题. 如果多个文件中对同一个符号进行了定义,也会出现重定义的问题 为什么会出现定义多次的问题呢? 回顾一下生成可执行二进制文件的过程
- 1/预处理
预处理阶段不可能出现重定义,不是说不可能出现,而是不可 能报错
- 2/编译
编辑的时候因为融合了很多文件,主要是.c文件和.h文件,因为一个.c文件包括很多.h文件. 这里面很可能出现重定义的问题,报错的话都是这么报的.多次声明不会报错 其实我在两个文件中分别 int i; 不会报错 file1: int i = 9; file2:int i; 也不会报错 file1: int i = 9; file2:int i = 8; 报错 linux@ubuntu:~/testForEVERYTHING$ gcc -S main.c -o main.o In file included from main.c:9:0: function2.h:8:5: error: redefinition of ‘i’ function1.h:8:5: note: previous definition of ‘i’ was here 这是我故意做的,当然现实情况下不会这么简单地出错.
- 3/汇编
汇编是按照编译后的文件转二进制的,只要是编译没问题,汇编就没问题
- 4/链接
链接的时候要根据调用文件中的函数引用 找到 目标文件或者共享目标文件中的原型.有多少个文件就从多少个文件中找,一个文件中有多少个就找多少个. linux@ubuntu:~/testForEVERYTHING$ gcc function1.o function2.o main.o -o main function2.o: In function `fun': function2.c:(.text+0x0): multiple definition of `fun' function1.o:function1.c:(.text+0x0): first defined here collect2: ld returned 1 exit status 意思是在 function2.o 中,有一个 fun 函数 ,fun函数在文件 function2.c中,多重定义 然而说function1.o中的是第一次定义,为什么会出现这种情况呢? 原因是先连接的前面的 linux@ubuntu:~/testForEVERYTHING$ gcc function2.o function1.o main.o -o main function1.o: In function `fun': function1.c:(.text+0x0): multiple definition of `fun' function2.o:function2.c:(.text+0x0): first defined here collect2: ld returned 1 exit status 当然,这是我人为故意链接了多个
编译实例分析
出现编译时重定义的时候非常多,尤其是在编译第三方源码的时候 在我编译busybox(busybox-1.17.3.tar.bz2)的时候出现了这个问题: In file included from /usr/include/linux/sysctl.h:25:0, from /usr/include/linux/netfilter.h:6, from /usr/include/linux/netfilter_ipv4.h:8, from networking/tcpudp.c:35: /usr/include/linux/kernel.h:12:8: error: redefinition of ‘struct sysinfo’ include/libbb.h:107:8: note: originally defined here make[1]: *** [networking/tcpudp.o] Error 1 make: *** [networking] Error 2 这个意思是在将networking/tcpudp.c编译成networking/tcpudp.o的时候,出现了一个问题 这个问题是编译的时候 一开始 在 include/libbb.h 中声明(我一般称之为声明)了一个struct sysinfo 这样的结构体类型, 然后/usr/include/linux/kernel.h文件中也声明了一个这样的类型 具体是这么包含的(下面这一段是我分析源码得到的,我不知道是不是可以根据log分析出来,因为没有其他问题的log供我分析) networking/tcpudp.c包含了include/libbb.h 和 /usr/include/linux/netfilter_ipv4.h /usr/include/linux/netfilter_ipv4.h包含了/usr/include/linux/netfilter.h /usr/include/linux/netfilter.h包含了/usr/include/linux/sysctl.h /usr/include/linux/sysctl.h包含了/usr/include/linux/kernel.h 也就是说 networking/tcpudp.c包含了include/libbb.h,间接包含了/usr/include/linux/kernel.h 然而,这两个.h文件中都有同一个声明,预处理的时候都弄到同一个文件里了,所以出现了重定义的问题 解决方案: 将/usr/include/linux/sysctl.h文件中包的/usr/include/linux/kernel.h这个删除掉,并添加一个include/libbb.h
链接实例分析
什么时候会出现问题
- 自己写
自己写的话,一般都是没什么问题的,连接的时候你把它加到 ld 后面就可以了,如果加重了会出现这个问题 所以说自己写和自己写的之间没什么问题
- 用动态库
动态库的话,如果是gcc自带的库,会根据xxx.h里面的xxx去指定位置找库文件,然后链接进去,其实连接的都是地址吧,我猜. 如果是移植的第三方库,也不会有什么问题,这个是根据gcc选项l后面加的东西去指定位置找的,然后连接进去,其实连接的也是地址. gcc自带的库之间没什么问题 移植的第三方库会不会和gcc自带的库冲突?好比说移植的第三方库调用了gcc自带的库,但是还是没连接进去,ld会帮忙重定位的. 第三方库之间有没有什么问题?应该会出现一些问题,例如里面可能用了同一个函数,两个库里面都有定义,那么会出现重定义的问题.
- 用静态库
用静态库的话,gcc自带的静态库之间没什么问题,他们是怎么处理的呢?如果A库用到了B库,A静态库里面是不是包括B静态库里面的东西? 是不包括的 第三方静态库如果像第三方动态库那样一个函数,两个定义,会不会有什么问题?静态库里面包没包gcc自带的静态库? 两个定义,自然会有问题 静态库里面不包括gcc自带的静态库
实例分析
------------------------------ 1 In file included from 2.h:8:0, from main.c:11: 22.h:8:5: error: redefinition of ‘i’ int i = 10; ^ In file included from 1.h:8:0, from main.c:10: 11.h:8:5: note: previous definition of ‘i’ was here int i = 9; ^ ------------------------------ 2 In file included from main.c:11:0: 2.h:8:5: error: redefinition of ‘i’ int i = 10; ^ In file included from 1.h:8:0, from main.c:10: 11.h:8:5: note: previous definition of ‘i’ was here int i = 9; ^ ------------------------------ 3 main.c:13:5: error: redefinition of ‘i’ int i = 10; ^ In file included from 1.h:8:0, from main.c:10: 11.h:8:5: note: previous definition of ‘i’ was here int i = 9; ^ ---------------------------------------------------- 编译问题 第1个示例中的 一个 i 定义在 22.h 中,另一个 i 定义在 11.h 中 第2个示例中的 一个 i 定义在 2.h 中,另一个 i 定义在 11.h 中 第3个示例中的 一个 i 定义在 main.c 中,另一个 i 定义在 11.h 中 ---------------------------------------------------- function1.o: In function `fun': function1.c:(.text+0x0): multiple definition of `fun' function2.o:function2.c:(.text+0x0): first defined here collect2: ld returned 1 exit status ---------------------------------------------------- 连接问题 编译成function1.o 的 function1.c 中 有 fun 的定义 编译成function2.o 的 function2.c 中 有 fun 的定义 ---------------------------------------------------- In file included from /usr/include/linux/sysctl.h:25:0, from /usr/include/linux/netfilter.h:6, from /usr/include/linux/netfilter_ipv4.h:8, from networking/tcpudp.c:35: /usr/include/linux/kernel.h:12:8: error: redefinition of ‘struct sysinfo’ include/libbb.h:107:8: note: originally defined here make[1]: *** [networking/tcpudp.o] Error 1 make: *** [networking] Error 2 ---------------------------------------------------- 编译问题 编译成 networking/tcpudp.o 的 networking/tcpudp.c 中包含的 include/libbb.h 声明了 struct sysinfo 编译成 networking/tcpudp.o 的 networking/tcpudp.c 中包含的 /usr/include/linux/netfilter_ipv4.h 包含的 /usr/include/linux/netfilter.h 包含的 /usr/include/linux/sysctl.h 包含的 /usr/include/linux/kernel.h 声明了 struct sysinfo ----------------------------------------------------
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/124706.html