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

大龍的博客

常用鏈接

統計

最新評論

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>
            亚洲电影毛片| 欧美日本一区二区视频在线观看| 久久九九精品| 欧美在线免费观看| 久久国产66| 免费人成精品欧美精品| 欧美高清在线一区二区| 亚洲三级观看| 亚洲毛片av| 一本久久综合亚洲鲁鲁五月天| 99在线精品免费视频九九视| 亚洲一区二区视频在线| 久久成人一区二区| 久久久久国产一区二区| 欧美va亚洲va国产综合| 国产精品v欧美精品∨日韩| 国产美女精品人人做人人爽| 欧美黄色aa电影| 亚洲综合电影| 久久综合色综合88| 亚洲精品日本| 先锋影院在线亚洲| 久久综合色婷婷| 国产精品久久久久久久9999| 精品动漫3d一区二区三区| 日韩视频―中文字幕| 欧美在线精品一区| 亚洲日本成人在线观看| 欧美一区二区三区免费视频| 欧美福利电影在线观看| 国产欧美日韩91| 日韩午夜免费视频| 免费美女久久99| 亚洲一区二区三区四区视频| 久久伊人精品天天| 国产精品萝li| 9i看片成人免费高清| 久久综合图片| 午夜精品视频| 国产精品mm| 欧美国产日韩免费| 国产综合色一区二区三区| 日韩一级黄色片| 欧美国产亚洲另类动漫| 欧美一区二区三区四区在线| 欧美色道久久88综合亚洲精品| 亚洲国产一二三| 美女精品在线| 久久综合成人精品亚洲另类欧美| 国产一区二区在线免费观看 | 国产一区二区三区高清播放| 99精品欧美一区二区蜜桃免费| 玖玖国产精品视频| 欧美中文在线观看| 久久成人精品无人区| 国产精品入口66mio| 亚洲一二区在线| 一本一本久久a久久精品综合麻豆| 免费不卡在线视频| 亚洲激情六月丁香| 欧美高清视频在线观看| 久久综合九色| 亚洲欧洲精品一区二区三区波多野1战4| 久久免费精品视频| 久久精品一区蜜桃臀影院| 国产亚洲欧美一区二区三区| 久久国产精品亚洲77777| 午夜一级久久| 国产一区三区三区| 玖玖国产精品视频| 欧美1区2区视频| 在线一区视频| 亚洲女性裸体视频| 激情综合色丁香一区二区| 欧美理论电影在线观看| 久久久免费av| 在线看国产日韩| 麻豆av一区二区三区| 久久久噜噜噜久久狠狠50岁| 亚洲国产精品一区| 亚洲肉体裸体xxxx137| 欧美日韩日本国产亚洲在线| 亚洲嫩草精品久久| 久久精品国产精品| 最新热久久免费视频| 亚洲精品国产精品乱码不99按摩 | 久久av一区二区三区漫画| 一区二区三区在线看| 亚洲第一页中文字幕| 欧美私人啪啪vps| 久久婷婷麻豆| 欧美日韩在线一区| 久久久久欧美精品| 欧美激情国产日韩精品一区18| 亚洲欧美一区二区三区久久| 欧美资源在线观看| 亚洲素人在线| 久久综合色婷婷| 欧美一级片久久久久久久| 免费h精品视频在线播放| 亚洲在线观看免费视频| 老司机精品视频网站| 午夜日韩电影| 欧美精品一区视频| 欧美成人第一页| 国产午夜精品一区二区三区视频| 亚洲第一网站| 一区二区自拍| 亚洲免费一在线| 亚洲午夜在线观看| 欧美顶级艳妇交换群宴| 久久免费高清视频| 国产欧美日韩一区二区三区在线观看 | 国产综合久久| 一区二区欧美日韩| 亚洲精品美女在线| 久久久999国产| 欧美一站二站| 国产精品美女久久福利网站| 亚洲欧洲中文日韩久久av乱码| 国内久久婷婷综合| 亚洲欧美日韩国产综合在线 | 久久免费视频观看| 欧美亚洲免费| 国产精品海角社区在线观看| 亚洲精品色图| 中日韩午夜理伦电影免费| 欧美国产日韩视频| 亚洲欧洲日韩在线| 日韩视频在线观看国产| 欧美大片在线看| 久久久五月天| 国产精品自在线| 亚洲欧美精品伊人久久| 亚洲欧美一区二区激情| 欧美日韩亚洲一区二| 亚洲肉体裸体xxxx137| 亚洲国产欧美久久| 免费毛片一区二区三区久久久| 久久久www成人免费精品| 国产欧美日韩另类一区 | 欧美国产欧美亚州国产日韩mv天天看完整 | 奶水喷射视频一区| 亚洲国产一区二区a毛片| 女同性一区二区三区人了人一| 欧美成人免费va影院高清| 亚洲国产另类 国产精品国产免费| 久久蜜桃香蕉精品一区二区三区| 欧美va亚洲va国产综合| 最新精品在线| 欧美午夜精品久久久久久超碰| 一区二区三区四区五区视频| 亚洲欧美精品一区| 国产日韩一区在线| 玖玖玖免费嫩草在线影院一区| 亚洲国产va精品久久久不卡综合| 亚洲另类在线视频| 国产精品s色| 久久久久久久综合狠狠综合| 欧美国产日韩一区二区| 亚洲一级二级在线| 国产一区二区三区久久悠悠色av | 国产精品日本欧美一区二区三区| 亚洲欧美第一页| 欧美电影免费观看高清| 一区二区三区视频在线观看| 国产精品视频免费一区| 久久久久久电影| 亚洲另类春色国产| 久久久久久久久岛国免费| 亚洲精品免费一区二区三区| 国产精品久久久久久久午夜 | 国产欧美日韩视频在线观看 | 亚洲第一页自拍| 欧美一激情一区二区三区| 亚洲国产精品久久久久秋霞影院 | 久久久蜜桃一区二区人| 日韩午夜av| 国语自产在线不卡| 欧美日韩另类国产亚洲欧美一级| 欧美一区二区三区另类| 日韩视频免费观看高清在线视频| 久久国产手机看片| 99精品久久免费看蜜臀剧情介绍| 国产伊人精品| 国产精品国产三级国产aⅴ入口 | 欧美高清在线| 先锋资源久久| 一区二区三区高清| 亚洲国产高清一区| 国产午夜精品美女毛片视频| 欧美日韩视频在线观看一区二区三区 | 久久精品免费看| 亚洲视频视频在线| 亚洲日韩中文字幕在线播放| 国产视频综合在线| 欧美午夜片欧美片在线观看| 欧美+日本+国产+在线a∨观看| 欧美在线影院| 亚洲欧美日韩精品一区二区|