13.强符号和弱符号
我們?cè)诰帉懘a的過程中經(jīng)常會(huì)遇到一種叫做符號(hào)重復(fù)定義(Multiple Definition)的錯(cuò)誤,這是因?yàn)樵诙鄠€(gè)源文件中定義了名字相同的全局變量,并且都將它們初始化了。
例如,在 a.c 中定義了全局變量 global:
int global = 10;在 b.c 中又對(duì) global 進(jìn)行了定義:
int global = 20;那么在鏈接時(shí)就會(huì)出現(xiàn)下面的錯(cuò)誤:
b.o: multiple definition of `global' a.o: first defined here這種符號(hào)的定義可以被稱為強(qiáng)符號(hào)。
在C語言中,編譯器默認(rèn)函數(shù)和初始化了的全局變量為強(qiáng)符號(hào)(Strong Symbol),未初始化的全局變量為弱符號(hào)(Weak Symbol)。強(qiáng)符號(hào)之所以強(qiáng),是因?yàn)樗鼈儞碛写_切的數(shù)據(jù),變量有值,函數(shù)有函數(shù)體;弱符號(hào)之所以弱,是因?yàn)樗鼈冞€未被初始化,沒有確切的數(shù)據(jù)。
鏈接器會(huì)按照如下的規(guī)則處理被多次定義的強(qiáng)符號(hào)和弱符號(hào):
1) 不允許強(qiáng)符號(hào)被多次定義,也即不同的目標(biāo)文件中不能有同名的強(qiáng)符號(hào);如果有多個(gè)強(qiáng)符號(hào),那么鏈接器會(huì)報(bào)符號(hào)重復(fù)定義錯(cuò)誤。
2) 如果一個(gè)符號(hào)在某個(gè)目標(biāo)文件中是強(qiáng)符號(hào),在其他文件中是弱符號(hào),那么選擇強(qiáng)符號(hào)。
3) 如果一個(gè)符號(hào)在所有的目標(biāo)文件中都是弱符號(hào),那么選擇其中占用空間最大的一個(gè)。
比如目標(biāo)文件 a.o 定義全局變量 global 為 int 類型,占用4個(gè)字節(jié),目標(biāo)文件 b.o 定義 global 為 double 類型,占用8個(gè)字節(jié),那么被鏈接后,符號(hào) global 占用8個(gè)字節(jié)。請(qǐng)盡量不要使用多個(gè)不同類型的弱符號(hào),否則有時(shí)候很難發(fā)現(xiàn)程序錯(cuò)誤。
在 GCC 中,可以通過__attribute__((weak))來強(qiáng)制定義任何一個(gè)符號(hào)為弱符號(hào)。假設(shè)現(xiàn)在有下面的一段代碼:
weak1 和 weak2 是弱符號(hào),strong 和 main 是強(qiáng)符號(hào),而 ext 既非強(qiáng)符號(hào)也非弱符號(hào),它是一個(gè)對(duì)外部變量的引用(使用)。
為了加深理解,我們不妨再來看一個(gè)多文件編程的例子。
main.c 源碼:
module.c 源碼:
#include <stdio.h> //強(qiáng)符號(hào) int a = 9999; void func(){printf("c.biancheng.net\n"); }在 GCC 中,使用下面的命令來運(yùn)行程序:
$gcc main.c module.c $./a.out a = 9999 c.biancheng.net在 main.c 中,a 和 func 都是弱符號(hào),在 module.c 中,a 和 func 都是強(qiáng)符號(hào),強(qiáng)符號(hào)會(huì)覆蓋弱符號(hào),所以鏈接器最終會(huì)使用 module.c 中的符號(hào),輸出結(jié)果也印證了這一點(diǎn)。
需要注意的是,__attribute__((weak))只對(duì)鏈接器有效,對(duì)編譯器不起作用,編譯器不區(qū)分強(qiáng)符號(hào)和弱符號(hào),只要在一個(gè)源文件中定義兩個(gè)相同的符號(hào),不管它們是強(qiáng)是弱,都會(huì)報(bào)“重復(fù)定義”錯(cuò)誤。請(qǐng)看下面代碼:
這段代碼在編譯階段就會(huì)報(bào)錯(cuò),編譯器會(huì)認(rèn)為變量 a 被定義了兩次,屬于重復(fù)定義。
弱符號(hào)對(duì)于庫來說十分有用,我們?cè)陂_發(fā)庫時(shí),可以將某些符號(hào)定義為弱符號(hào),這樣就能夠被用戶定義的強(qiáng)符號(hào)覆蓋,從而使得程序可以使用自定義版本的函數(shù),增加了很大的靈活性。
本文轉(zhuǎn)自:強(qiáng)符號(hào)和弱符號(hào)
轉(zhuǎn)載于:https://www.cnblogs.com/yongdaimi/p/8084634.html
總結(jié)
以上是生活随笔為你收集整理的13.强符号和弱符号的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: axure7.0 汉化包下载
- 下一篇: android自动计步_Android计