日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

重定义

發布時間:2023/12/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 重定义 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

重定義是什么

重定義就是定義了多次一般解決重定義的方法是用宏指令 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 hereint 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 hereint 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 hereint 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 ----------------------------------------------------

總結

以上是生活随笔為你收集整理的重定义的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。