青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

大龍的博客

常用鏈接

統(tǒng)計(jì)

最新評(píng)論

GCC中的弱符號(hào)與強(qiáng)符號(hào)

我們經(jīng)常在編程中碰到一種情況叫符號(hào)重復(fù)定義。多個(gè)目標(biāo)文件中含有相同名字全局符號(hào)的定義,那么這些目標(biāo)文件鏈接的時(shí)候?qū)?huì)出現(xiàn)符號(hào)重復(fù)定義的錯(cuò)誤。比如我們?cè)谀繕?biāo)文件A和目標(biāo)文件B都定義了一個(gè)全局整形變量global,并將它們都初始化,那么鏈接器將A和B進(jìn)行鏈接時(shí)會(huì)報(bào)錯(cuò):
1 b.o:(.data+0x0): multiple definition of `global'
2 a.o:(.data+0x0): first defined here

 

        這種符號(hào)的定義可以被稱為強(qiáng)符號(hào)(Strong Symbol)。有些符號(hào)的定義可以被稱為弱符號(hào)(Weak Symbol)。
對(duì)于C/C++語言來說,編譯器默認(rèn)函數(shù)和初始化了的全局變量為強(qiáng)符號(hào),未初始化的全局變量為弱符號(hào)。我們也可以通過GCC的"__attribute__((weak))"來定義任何一個(gè)強(qiáng)符號(hào)為弱符號(hào)。注意,強(qiáng)符號(hào)和弱符號(hào)都是針對(duì)定義來說的,不是針對(duì)符號(hào)的引用。比如我們有下面這段程序:
extern int ext;
int weak;
int strong = 1;
__attribute__((weak)) weak2 = 2;
int main()
{
        return 0;
}

 
上面這段程序中,"weak"和"weak2"是弱符號(hào),"strong"和"main"是強(qiáng)符號(hào),而"ext"既非強(qiáng)符號(hào)也非弱符號(hào),因?yàn)樗且粋€(gè)外部變量的引用。
針對(duì)強(qiáng)弱符號(hào)的概念,鏈接器就會(huì)按如下規(guī)則處理與選擇被多次定義的全局符號(hào):
規(guī)則1:不允許強(qiáng)符號(hào)被多次定義(即不同的目標(biāo)文件中不能有同名的強(qiáng)符號(hào));如果有多個(gè)強(qiáng)符號(hào)定義,則鏈接器報(bào)符號(hào)重復(fù)定義錯(cuò)誤。
規(guī)則2:如果一個(gè)符號(hào)在某個(gè)目標(biāo)文件中是強(qiáng)符號(hào),在其他文件中都是弱符號(hào),那么選擇強(qiáng)符號(hào)。
規(guī)則3:如果一個(gè)符號(hào)在所有目標(biāo)文件中都是弱符號(hào),那么選擇其中占用空間最大的一個(gè)。比如目標(biāo)文件A定義全局變量global為int型,占4個(gè)字節(jié);目標(biāo)文件B定義global為double型,占8個(gè)字節(jié),那么目標(biāo)文件A和B鏈接后,符號(hào)global占8個(gè)字節(jié)(盡量不要使用多個(gè)不同類型的弱符號(hào),否則容易導(dǎo)致很難發(fā)現(xiàn)的程序錯(cuò)誤)。

弱引用和強(qiáng)引用 

目前我們所看到的對(duì)外部目標(biāo)文件的符號(hào)引用在目標(biāo)文件被最終鏈接成可執(zhí)行文件時(shí),它們須要被正確決議,如果沒有找到該符號(hào)的定義,鏈接器就會(huì)報(bào)符號(hào)未定義錯(cuò)誤,這種被稱為強(qiáng)引用(Strong Reference)。與之相對(duì)應(yīng)還有一種弱引用(Weak Reference),在處理弱引用時(shí),如果該符號(hào)有定義,則鏈接器將該符號(hào)的引用決議;如果該符號(hào)未被定義,則鏈接器對(duì)于該引用不報(bào)錯(cuò)。鏈接器處理強(qiáng)引用和弱引用的過程幾乎一樣,只是對(duì)于未定義的弱引用,鏈接器不認(rèn)為它是一個(gè)錯(cuò)誤。一般對(duì)于未定義的弱引用,鏈接器默認(rèn)其為0,或者是一個(gè)特殊的值,以便于程序代碼能夠識(shí)別。
在GCC中,我們可以通過使用"__attribute__((weakref))"這個(gè)擴(kuò)展關(guān)鍵字來聲明對(duì)一個(gè)外部函數(shù)的引用為弱引用,比如下面這段代碼:
1 __attribute__ ((weakref)) void foo();
2 int main()
3 {
4         foo();
5 }
6

 
我們可以將它編譯成一個(gè)可執(zhí)行文件,GCC并不會(huì)報(bào)鏈接錯(cuò)誤。但是當(dāng)我們運(yùn)行這個(gè)可執(zhí)行文件時(shí),會(huì)發(fā)生運(yùn)行錯(cuò)誤。因?yàn)楫?dāng)main函數(shù)試圖調(diào)用foo函數(shù)時(shí),foo函數(shù)的地址為0,于是發(fā)生了非法地址訪問的錯(cuò)誤。一個(gè)改進(jìn)的例子是:
1 __attribute__ ((weakref)) void foo();
2 int main()
3 {
4         if (foo)
5                foo();
6 }
7

 
      這種弱符號(hào)和弱引用對(duì)于庫(kù)來說十分有用,比如庫(kù)中定義的弱符號(hào)可以被用戶定義的強(qiáng)符號(hào)所覆蓋,從而使得程序可以使用自定義版本的庫(kù)函數(shù);或者程序可以對(duì)某些擴(kuò)展功能模塊的引用定義為弱引用,當(dāng)我們將擴(kuò)展模塊與程序鏈接在一起時(shí),功能模塊就可以正常使用;如果我們?nèi)サ袅四承┕δ苣K,那么程序也可以正常鏈接,只是缺少了相應(yīng)的功能,這使得程序的功能更加容易裁剪和組合。
      在Linux程序的設(shè)計(jì)中,如果一個(gè)程序被設(shè)計(jì)成可以支持單線程或多線程的模式,就可以通過弱引用的方法來判斷當(dāng)前的程序是鏈接到了單線程的Glibc庫(kù)還是多線程的Glibc庫(kù)(是否在編譯時(shí)有-lpthread選項(xiàng)),從而執(zhí)行單線程版本的程序或多線程版本的程序。我們可以在程序中定義一個(gè)pthread_create函數(shù)的弱引用,然后程序在運(yùn)行時(shí)動(dòng)態(tài)判斷是否鏈接到pthread庫(kù)從而決定執(zhí)行多線程版本還是單線程版本:
 1 #include <stdio.h>
 2 #include <pthread.h>
 3 int pthread_create( pthread_t*, const pthread_attr_t*,
 4 void* (*)(void*), void*) __attribute__ ((weak));
 5 int main()
 6 {
 7     if(pthread_create)
 8     {
 9             printf("This is multi-thread version!\n");
10             // run the multi-thread version
11             // main_multi_thread()
12     }
13     else
14     {
15             printf("This is single-thread version!\n");  
16             // run the single-thread version
17             // main_single_thread()
18     }
19 }
20

 
編譯運(yùn)行結(jié)果如下:
1 $ gcc pthread.c -o pt
2 $ ./pt
3 This is single-thread version!
4 $ gcc pthread.c -lpthread -o pt
5 $ ./pt
6 This is multi-thread version!

 

在GCC的官方文檔中,對(duì)weak和weakref的描述如下:
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes

weak
The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.

weakref
weakref ("target")
The weakref attribute marks a declaration as a weak reference.
Without arguments, it should be accompanied by an alias attribute naming the target symbol. Optionally, the target may be given as an argument to weakref itself. In either case, weakref implicitly marks the declaration as weak. Without a target, given as an argument to weakref or to alias, weakref is equivalent to weak.
1     static int x() __attribute__ ((weakref ("y")));
2     /* is equivalent to... */
3     static int x() __attribute__ ((weak, weakref, alias ("y")));
4     /* and to... */
5     static int x() __attribute__ ((weakref));
6     static int x() __attribute__ ((alias ("y")));

 
    
A weak reference is an alias that does not by itself require a definition to be given for the target symbol. If the target symbol is only referenced through weak references, then the becomes a weak undefined symbol. If it is directly referenced, however, then such strong references prevail, and a definition will be required for the symbol, not necessarily in the same translation unit.
The effect is equivalent to moving all references to the alias to a separate translation unit, renaming the alias to the aliased symbol, declaring it as weak, compiling the two separate translation units and performing a reloadable link on them.
At present, a declaration to which weakref is attached can only be static.

posted on 2010-05-23 21:50 大龍 閱讀(833) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区三区欧美 | 国产在线一区二区三区四区| 亚洲视频一区二区免费在线观看| 亚洲精品国产精品乱码不99按摩| 免费成人黄色av| 一区二区三区**美女毛片 | 欧美一区二区啪啪| 欧美亚洲综合久久| 1024亚洲| 亚洲美女av在线播放| 国产精品s色| 久久精品人人做人人综合| 久久亚洲午夜电影| 一区二区三区回区在观看免费视频| 一本色道久久综合亚洲二区三区| 国产精品区二区三区日本| 久久蜜桃精品| 欧美日韩hd| 久久亚洲免费| 欧美人与性禽动交情品| 欧美在线观看网站| 欧美成人午夜激情| 欧美一区二区成人6969| 可以免费看不卡的av网站| 日韩视频二区| 欧美一级淫片播放口| 亚洲国产中文字幕在线观看| 亚洲视频在线观看网站| 1204国产成人精品视频| 一区二区三区高清| 亚洲国产视频直播| 性xx色xx综合久久久xx| 99pao成人国产永久免费视频| 亚洲欧美视频在线观看| 亚洲美女一区| 久久午夜精品| 欧美一区二区视频在线| 欧美精品v日韩精品v国产精品| 欧美有码在线视频| 欧美日韩精品三区| 欧美大成色www永久网站婷| 国产乱人伦精品一区二区 | 亚洲精品无人区| 国内精品视频一区| 亚洲一线二线三线久久久| 亚洲精选在线| 久久综合影音| 久久乐国产精品| 国产精品久久久久久久久久久久久久| 欧美成人精品影院| 国产在线成人| 欧美一区深夜视频| 小黄鸭精品密入口导航| 欧美日韩中文字幕综合视频| 欧美激情久久久| 在线观看91久久久久久| 欧美在线视频a| 欧美在线播放视频| 国产精品视频免费一区| 一区二区三区产品免费精品久久75 | 欧美日韩国产免费| 欧美国产免费| 亚洲国产精品一区制服丝袜 | 久久这里只有| 美女黄毛**国产精品啪啪 | 欧美第一黄网免费网站| 欧美国产免费| 亚洲精选大片| 欧美日韩亚洲91| 亚洲精品少妇30p| 在线亚洲美日韩| 国产精品久久久久久亚洲调教| 一本色道88久久加勒比精品| 夜夜嗨av一区二区三区四季av| 欧美国产高潮xxxx1819| 亚洲激情网址| 亚洲桃花岛网站| 国产精品免费福利| 久久大逼视频| 欧美成人一区二区三区在线观看 | 亚洲欧美综合国产精品一区| 欧美色视频在线| 亚洲午夜久久久久久久久电影院| 午夜精品在线| 一区二区三区在线视频观看| 久久综合婷婷| 一区二区三区视频观看| 久久se精品一区精品二区| 国内精品伊人久久久久av影院 | 欧美日韩18| 亚洲一区二三| 麻豆成人在线| 日韩视频中文| 国产偷自视频区视频一区二区| 久久精品女人的天堂av| 亚洲成在人线av| 午夜日韩福利| 亚洲国产合集| 国产精品久久久久毛片大屁完整版 | 国产精品久久久久国产精品日日 | 国产精品99久久久久久久vr | 老色鬼精品视频在线观看播放| 亚洲人成亚洲人成在线观看图片| 欧美日韩国产小视频| 先锋资源久久| 亚洲人午夜精品| 久久久成人网| 亚洲性夜色噜噜噜7777| 在线高清一区| 国产欧美日韩亚洲精品| 欧美国内亚洲| 久久久国际精品| 亚洲午夜极品| 亚洲美女视频在线观看| 久久综合九色综合欧美狠狠| 亚洲永久免费精品| 亚洲激情在线| 激情婷婷亚洲| 国产欧美一区二区三区国产幕精品| 欧美α欧美αv大片| 欧美在线视频一区二区三区| 一本色道久久综合亚洲精品按摩 | 亚洲国产毛片完整版| 久久精品人人做人人爽| 亚洲视频一二| 99视频精品在线| 亚洲国产精品久久久久婷婷老年| 国产女主播一区二区三区| 欧美视频精品一区| 欧美精品一区二区三区在线播放| 久久久久久久久蜜桃| 香港成人在线视频| 亚洲男人av电影| 一区二区三区黄色| 99国产精品自拍| 亚洲国产成人一区| 亚洲电影免费| 亚洲人成久久| 亚洲日本欧美| 亚洲精选在线| 日韩天堂av| 一区二区三区产品免费精品久久75| 亚洲日韩欧美视频| 亚洲黄色毛片| 亚洲精品国产精品国自产观看浪潮| 欧美成人网在线| 欧美激情精品久久久久久| 欧美岛国在线观看| 亚洲大片免费看| 亚洲国产欧美日韩另类综合| 亚洲大胆av| 亚洲精品在线观看视频| 99成人在线| 中国女人久久久| 亚洲欧美成人一区二区在线电影| 亚洲欧美日韩在线播放| 欧美在线播放一区二区| 久久九九精品99国产精品| 久久一区视频| 欧美精品一区二区三区蜜臀| 欧美日韩在线播放三区四区| 欧美午夜www高清视频| 国产精品色婷婷久久58| 国产一区二区三区丝袜| 亚洲国产欧美久久| 中国日韩欧美久久久久久久久| 亚洲男人第一av网站| 久久天堂国产精品| 欧美高清在线视频| 日韩一区二区精品| 小处雏高清一区二区三区| 久久综合免费视频影院| 欧美日韩国产页| 国产亚洲欧美日韩一区二区| 1024成人| 亚洲在线成人精品| 老司机亚洲精品| 99精品99| 久久亚洲午夜电影| 欧美视频观看一区| 在线电影院国产精品| 亚洲香蕉视频| 欧美电影免费观看| 亚洲一区激情| 欧美激情按摩| 激情五月婷婷综合| 亚洲香蕉伊综合在人在线视看| 久久久成人网| 一区二区三区日韩精品| 久热精品视频在线观看| 国产女同一区二区| 宅男噜噜噜66一区二区66| 美女成人午夜| 亚洲欧美在线免费观看| 欧美精品一区三区在线观看| 国产在线欧美| 欧美一区二区| 中文在线资源观看视频网站免费不卡| 久久久久一本一区二区青青蜜月| 国产精品啊v在线|