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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

13.强符号和弱符号

發(fā)布時(shí)間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 13.强符号和弱符号 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們?cè)诰帉懘a的過(guò)程中經(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語(yǔ)言中,編譯器默認(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)樗鼈冞€未被初始化,沒(méi)有確切的數(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 中,可以通過(guò)__attribute__((weak))來(lái)強(qiáng)制定義任何一個(gè)符號(hào)為弱符號(hào)。假設(shè)現(xiàn)在有下面的一段代碼:

extern int ext; int weak1; int strong = 100; __attribute__((weak)) weak2 = 2; int main(){return 0; }

weak1 和 weak2 是弱符號(hào),strong 和 main 是強(qiáng)符號(hào),而 ext 既非強(qiáng)符號(hào)也非弱符號(hào),它是一個(gè)對(duì)外部變量的引用(使用)。

為了加深理解,我們不妨再來(lái)看一個(gè)多文件編程的例子。

main.c 源碼:

#include <stdio.h> //弱符號(hào) __attribute__((weak)) int a = 20; __attribute__((weak)) void func(){printf("C Language\n"); } int main(){printf("a = %d\n", a);func();return 0; }

module.c 源碼:

#include <stdio.h> //強(qiáng)符號(hào) int a = 9999; void func(){printf("c.biancheng.net\n"); }

在 GCC 中,使用下面的命令來(lái)運(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)看下面代碼:

#include <stdio.h> __attribute__((weak)) int a = 20; int a = 9999; int main(){printf("a = %d\n", a);return 0; }

這段代碼在編譯階段就會(huì)報(bào)錯(cuò),編譯器會(huì)認(rèn)為變量 a 被定義了兩次,屬于重復(fù)定義。

弱符號(hào)對(duì)于庫(kù)來(lái)說(shuō)十分有用,我們?cè)陂_發(fā)庫(kù)時(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.强符号和弱符号的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。