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

大龍的博客

常用鏈接

統計

最新評論

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 大龍 閱讀(839) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   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精品久久久久久| 欧美日韩高清在线| 一本色道久久99精品综合 | 国内精品视频在线播放| 久久成人免费视频| 欧美一区亚洲二区| 一区二区三区在线视频观看| 噜噜噜91成人网| 欧美风情在线| 亚洲欧美日韩另类| 欧美一区不卡| 日韩一区二区电影网| 99伊人成综合| 伊人久久婷婷色综合98网| 欧美激情亚洲自拍| 国产精品久久国产三级国电话系列 | 亚洲国产精品美女| 免费看的黄色欧美网站| 能在线观看的日韩av| 亚洲视频www| 久久精品五月| 一区二区福利| 久久黄色影院| 亚洲一区在线观看免费观看电影高清| 亚洲伊人网站| 亚洲日本视频| 午夜欧美大片免费观看| 在线电影欧美日韩一区二区私密| 亚洲国产一区二区三区在线播| 欧美日韩国产综合网 | 午夜精品区一区二区三| 久久国产精品一区二区三区| 99热精品在线| 久久亚洲一区二区三区四区| 亚洲视频成人| 欧美黑人国产人伦爽爽爽| 羞羞色国产精品| 欧美日韩国产精品自在自线| 久久久久成人精品免费播放动漫| 欧美激情久久久久| 欧美电影电视剧在线观看| 国产精品视频99| 亚洲免费播放| 亚洲欧洲日夜超级视频| 久久不射2019中文字幕| 亚洲一区二区三区精品在线观看| 久久综合九色综合欧美狠狠| 欧美一区二区三区四区夜夜大片| 欧美日韩成人一区二区| 欧美国产精品v| 国内精品福利| 欧美在线播放一区| 欧美一区二区在线播放| 国产精品久久久久久亚洲调教| 亚洲国产精品综合| 91久久精品国产91久久性色tv | 99国产精品久久久久久久久久| 在线观看视频一区| 久久久久久电影| 久久亚洲国产精品一区二区| 国产精品自拍三区| 欧美一区二区三区在线观看| 亚洲欧美另类国产| 国产精品青草久久久久福利99| 9i看片成人免费高清| 亚洲午夜免费福利视频| 国产精品爱啪在线线免费观看| 亚洲美女精品成人在线视频| 在线视频欧美日韩精品| 欧美四级伦理在线| 亚洲视频精品在线| 久久xxxx| 在线观看日韩av电影| 老鸭窝亚洲一区二区三区| 久久青青草综合| 亚洲国产美女精品久久久久∴| 卡一卡二国产精品| 亚洲精品国精品久久99热一| 一本色道久久综合亚洲精品小说| 欧美日韩在线播放三区| 亚洲男女自偷自拍| 久热国产精品视频| 亚洲精品国产精品国自产在线| 欧美激情小视频| 中国女人久久久| 久久理论片午夜琪琪电影网| 亚洲国产第一| 欧美午夜电影完整版| 欧美亚洲在线观看| 91久久国产精品91久久性色| 亚洲婷婷综合久久一本伊一区| 国产精品你懂得| 裸体女人亚洲精品一区| 亚洲精品日韩在线观看| 欧美在线视频导航| 亚洲日本成人| 国产精品一区在线播放| 免费欧美视频| 亚洲综合视频1区| 亚洲电影一级黄| 久久国产精品一区二区| 日韩午夜av在线| 国产一区二区三区av电影| 欧美成人中文字幕| 亚洲女爱视频在线| 亚洲激情六月丁香| 久久三级视频| 亚洲字幕一区二区| 91久久久亚洲精品| 国产综合久久久久影院| 国产精品大片| 欧美国产精品va在线观看| 午夜激情综合网| 亚洲美女福利视频网站| 欧美粗暴jizz性欧美20| 欧美在线3区| 亚洲一区二区视频在线| 91久久极品少妇xxxxⅹ软件| 国产亚洲福利社区一区| 国产精品福利网站| 欧美久久在线| 欧美成人小视频| 久久亚洲国产精品一区二区| 亚洲免费在线| 亚洲一区自拍| 在线视频日韩| 日韩视频一区二区在线观看| 欧美国产日韩亚洲一区| 久久婷婷一区| 久久久久综合网| 久久免费一区| 久久久久九九九九| 久久国产精品一区二区| 久久av一区二区三区| 性18欧美另类| 欧美一区二区三区在线观看视频| 国产精品99久久久久久久vr| 亚洲日本中文字幕| 亚洲精品久久久久久久久| 亚洲国产成人久久综合一区| 在线成人欧美| 亚洲精品欧美| 日韩亚洲欧美一区二区三区| 亚洲精品乱码久久久久久按摩观 | 国内精品久久久久影院色| 国产人成精品一区二区三| 国产精品剧情在线亚洲| 国产精品免费观看视频| 国产精品网曝门| 国产亚洲一区二区精品| 国产欧美日本一区视频| 国产一区二区精品在线观看| 国产一区二区三区久久久久久久久| 国产精品最新自拍| 狠狠色综合色综合网络| 亚洲高清在线观看一区| 一本久久综合亚洲鲁鲁五月天| 99国产精品久久久| 亚洲欧美日韩一区二区在线| 午夜日韩在线观看| 蜜桃av综合| 亚洲国产欧美一区| 亚洲免费电影在线| 欧美一区二区三区在线看| 久久人人97超碰精品888| 欧美黑人一区二区三区| 国产精品免费aⅴ片在线观看| 国产亚洲一区二区三区| 亚洲日本在线观看| 午夜在线成人av| 欧美成熟视频| 亚洲午夜黄色| 久久综合狠狠综合久久综青草 | 亚洲免费在线电影| 久久综合中文色婷婷| 欧美日韩一区二区免费在线观看| 国产精品网站在线| 最近中文字幕日韩精品| 亚洲一区中文| 欧美激情按摩在线| 亚洲一区二区三区中文字幕| 久久久久久久综合色一本| 欧美美女视频| 伊人久久综合| 亚洲欧美日本国产有色| 欧美大片免费| 午夜精品久久99蜜桃的功能介绍| 另类天堂av| 国产亚洲a∨片在线观看| 日韩视频免费在线| 久久亚洲春色中文字幕| 亚洲网在线观看| 免费日韩成人| 在线成人av.com| 久久福利影视| 亚洲午夜一区二区三区| 欧美激情视频在线播放| 在线播放视频一区| 久久综合电影|