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

大龍的博客

常用鏈接

統計

最新評論

GCC中的弱符號與強符號

我們經常在編程中碰到一種情況叫符號重復定義。多個目標文件中含有相同名字全局符號的定義,那么這些目標文件鏈接的時候將會出現符號重復定義的錯誤。比如我們在目標文件A和目標文件B都定義了一個全局整形變量global,并將它們都初始化,那么鏈接器將A和B進行鏈接時會報錯:
1 b.o:(.data+0x0): multiple definition of `global'
2 a.o:(.data+0x0): first defined here

 

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

 
上面這段程序中,"weak"和"weak2"是弱符號,"strong"和"main"是強符號,而"ext"既非強符號也非弱符號,因為它是一個外部變量的引用。
針對強弱符號的概念,鏈接器就會按如下規則處理與選擇被多次定義的全局符號:
規則1:不允許強符號被多次定義(即不同的目標文件中不能有同名的強符號);如果有多個強符號定義,則鏈接器報符號重復定義錯誤。
規則2:如果一個符號在某個目標文件中是強符號,在其他文件中都是弱符號,那么選擇強符號。
規則3:如果一個符號在所有目標文件中都是弱符號,那么選擇其中占用空間最大的一個。比如目標文件A定義全局變量global為int型,占4個字節;目標文件B定義global為double型,占8個字節,那么目標文件A和B鏈接后,符號global占8個字節(盡量不要使用多個不同類型的弱符號,否則容易導致很難發現的程序錯誤)。

弱引用和強引用 

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

 
我們可以將它編譯成一個可執行文件,GCC并不會報鏈接錯誤。但是當我們運行這個可執行文件時,會發生運行錯誤。因為當main函數試圖調用foo函數時,foo函數的地址為0,于是發生了非法地址訪問的錯誤。一個改進的例子是:
1 __attribute__ ((weakref)) void foo();
2 int main()
3 {
4         if (foo)
5                foo();
6 }
7

 
      這種弱符號和弱引用對于庫來說十分有用,比如庫中定義的弱符號可以被用戶定義的強符號所覆蓋,從而使得程序可以使用自定義版本的庫函數;或者程序可以對某些擴展功能模塊的引用定義為弱引用,當我們將擴展模塊與程序鏈接在一起時,功能模塊就可以正常使用;如果我們去掉了某些功能模塊,那么程序也可以正常鏈接,只是缺少了相應的功能,這使得程序的功能更加容易裁剪和組合。
      在Linux程序的設計中,如果一個程序被設計成可以支持單線程或多線程的模式,就可以通過弱引用的方法來判斷當前的程序是鏈接到了單線程的Glibc庫還是多線程的Glibc庫(是否在編譯時有-lpthread選項),從而執行單線程版本的程序或多線程版本的程序。我們可以在程序中定義一個pthread_create函數的弱引用,然后程序在運行時動態判斷是否鏈接到pthread庫從而決定執行多線程版本還是單線程版本:
 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

 
編譯運行結果如下:
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的官方文檔中,對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 大龍 閱讀(825) 評論(0)  編輯 收藏 引用

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美成人中文字幕| 国产日韩精品在线观看| 欧美一级大片在线免费观看| 美女主播精品视频一二三四| 欧美一级午夜免费电影| 欧美日韩国产在线播放| 欧美 日韩 国产在线| 国产一区观看| 午夜精彩视频在线观看不卡| 一区二区三区精密机械公司 | 欧美激情一区二区三级高清视频| 亚洲男人的天堂在线观看| 欧美大片免费观看在线观看网站推荐| 久久精品国产综合| 国产一区二区久久精品| 午夜精品久久久久久| 欧美怡红院视频一区二区三区| 欧美日韩成人在线播放| 亚洲激情一区| 今天的高清视频免费播放成人| 一区二区欧美在线| 一本色道久久综合精品竹菊| 欧美大片第1页| 亚洲精品免费在线观看| 亚洲性视频h| 欧美调教视频| 亚洲第一区色| 在线成人免费观看| 久久午夜视频| 另类国产ts人妖高潮视频| 好吊色欧美一区二区三区视频| 亚欧成人精品| 久久一区二区视频| 亚洲电影在线看| 麻豆精品视频在线观看| 欧美一区二区三区四区视频| 国产亚洲毛片在线| 欧美一级专区| 亚洲国产另类精品专区 | 国内久久精品| 美女在线一区二区| 亚洲经典三级| 亚洲欧美日韩国产综合精品二区| 国产精品综合av一区二区国产馆| 久久精品国产亚洲一区二区| 欧美福利一区| 亚洲一区二区三区在线观看视频| 国产精品美女| 久久亚洲一区二区| 亚洲毛片在线| 久久成人免费| 日韩一区二区精品视频| 国产精品久久久久久久免费软件 | 久久久久久9| 国内精品国产成人| 欧美 日韩 国产一区二区在线视频| 久久久视频精品| 一本色道久久综合亚洲精品小说| 国产精品久久久亚洲一区| 久久久av水蜜桃| 99re6这里只有精品视频在线观看| 午夜欧美理论片| 91久久精品久久国产性色也91 | 美女国产一区| 亚洲精品日韩精品| 久久久久国产精品午夜一区| 亚洲美女黄色片| 国产一级精品aaaaa看| 欧美激情一区二区三区蜜桃视频| 亚洲一区欧美激情| 亚洲精品国产欧美| 女主播福利一区| 久久精品av麻豆的观看方式| 亚洲精品欧美在线| 国模吧视频一区| 国产精品久久久久久久久借妻 | 久久久精彩视频| 亚洲视频国产视频| 亚洲国产日韩欧美在线图片| 国产精品美女黄网| 欧美日韩亚洲一区二区三区在线 | 久久亚洲二区| 欧美一区二区视频免费观看| 一本色道久久综合亚洲精品小说 | 小处雏高清一区二区三区| 亚洲人成网站精品片在线观看| 乱人伦精品视频在线观看| 亚洲欧美日本日韩| 中文高清一区| 亚洲免费精品| 日韩网站在线观看| 亚洲国产日韩欧美| 影音先锋中文字幕一区| 国产午夜精品久久久久久免费视| 国产精品国产自产拍高清av王其| 欧美精品三级在线观看| 欧美 日韩 国产 一区| 久久一区二区三区av| 久久婷婷激情| 久久久精品日韩| 久久高清一区| 亚洲免费人成在线视频观看| 一区二区三区毛片| 一区二区高清视频在线观看| 亚洲免费av片| 亚洲无线一线二线三线区别av| 一区二区三区导航| 亚洲视频精选在线| 亚洲图片欧洲图片av| 99精品视频免费| 一区二区三区久久精品| 亚洲一区二三| 午夜精品久久久久久久99樱桃 | 国产精品99久久久久久久久久久久 | 国产一区二区三区网站| 国产性色一区二区| 在线观看91精品国产入口| 亚洲成人影音| 亚洲乱码国产乱码精品精98午夜| 亚洲精品在线观看免费| 亚洲天堂男人| 久久精品道一区二区三区| 久久久噜噜噜久久中文字免| 免费成年人欧美视频| 欧美激情1区2区3区| 亚洲三级电影在线观看| 在线一区日本视频| 欧美影院一区| 久久综合给合| 欧美极品aⅴ影院| 欧美午夜视频一区二区| 国产日韩欧美在线播放| 激情欧美丁香| 99xxxx成人网| 亚洲免费电影在线观看| 午夜一区二区三区在线观看| 久久只有精品| 亚洲伦理在线| 久久精品亚洲精品| 欧美人成在线| 国产亚洲一区二区三区| 亚洲国产黄色片| 亚洲男人的天堂在线观看| 久久久久久一区二区| 亚洲精品日韩一| 欧美一区二区三区四区在线观看| 免费人成网站在线观看欧美高清| 欧美日韩在线视频一区| 黄色成人在线网址| 亚洲一级二级| 免费中文日韩| 亚洲在线观看| 欧美日韩国产限制| 黄色亚洲在线| 午夜精品久久99蜜桃的功能介绍| 蜜桃av一区二区| 午夜一区不卡| 欧美日韩在线大尺度| 136国产福利精品导航网址| 亚洲欧美色一区| 亚洲国产精品久久久| 羞羞视频在线观看欧美| 欧美日韩在线看| 亚洲国产毛片完整版| 久久久久久久久蜜桃| 99视频在线精品国自产拍免费观看| 久久亚洲一区二区| 国产一区二区三区在线观看视频| 亚洲性图久久| 亚洲欧洲在线免费| 老司机午夜精品| 国产综合香蕉五月婷在线| 亚洲一区网站| 日韩视频免费观看| 欧美成人久久| 亚洲激情av在线| 欧美大秀在线观看| 久久精品日韩| 国内外成人在线| 久久国产精品72免费观看| 在线中文字幕一区| 欧美视频一区在线| 9国产精品视频| 亚洲片在线观看| 欧美国产精品v| 亚洲精品久久久久久久久久久久 | 亚洲三级性片| 欧美猛交免费看| 国产精品99久久久久久人| 亚洲美女一区| 国产精品久久久久毛片软件| 亚洲一区二区三区午夜| 在线一区二区日韩| 国产精品日韩一区| 久久精品盗摄| 久久久久综合网| 亚洲国产精品久久久久婷婷884| 美女视频黄a大片欧美| 老鸭窝毛片一区二区三区| 亚洲高清在线播放|