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

大龍的博客

常用鏈接

統計

最新評論

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>
            欧美视频一区二区| 国产精品成人播放| 亚洲国产成人精品视频| 欧美不卡一卡二卡免费版| 久久综合网络一区二区| 一本色道久久88亚洲综合88| 在线亚洲一区| 精品1区2区3区4区| 亚洲激情视频在线观看| 欧美午夜精品久久久久久人妖 | 国产麻豆成人精品| 久久久91精品国产一区二区精品| 久久久久久亚洲精品中文字幕 | 欧美在线观看www| 久久综合给合| 亚洲一区日韩| 久久亚洲春色中文字幕| 亚洲一区二区三区午夜| 欧美影院精品一区| 亚洲网站啪啪| 久热爱精品视频线路一| 亚洲一区黄色| 免费高清在线一区| 午夜免费电影一区在线观看| 久热精品视频| 欧美在线综合视频| 欧美日本三级| 欧美二区乱c少妇| 国产精品入口夜色视频大尺度 | 久久男女视频| 99国内精品| 久久久免费精品视频| 亚洲一区免费看| 欧美sm视频| 久久视频在线免费观看| 国产精品欧美日韩一区二区| 欧美国产日韩视频| 激情久久五月天| 亚洲嫩草精品久久| 亚洲一级特黄| 欧美日韩中文字幕精品| 亚洲国产精品毛片| 在线精品国产欧美| 久久精品国产久精国产爱| 午夜精品久久久久久久99水蜜桃 | 亚洲高清视频的网址| 久久精品1区| 久久久精品午夜少妇| 国产免费成人| 亚洲天堂成人在线观看| 亚洲午夜久久久| 欧美日韩精品不卡| 亚洲精美视频| 99人久久精品视频最新地址| 你懂的国产精品永久在线| 麻豆精品91| 亚洲国产精品成人综合| 美女黄色成人网| 欧美大片免费久久精品三p| 在线观看成人一级片| 久久久久高清| 欧美国产日韩免费| 亚洲伦理自拍| 欧美日韩八区| 亚洲视频香蕉人妖| 欧美一区二区精品久久911| 国产欧美欧美| 久久精品首页| 亚洲第一伊人| 亚洲天堂av在线免费| 国产精品国产三级国产专播精品人| 99国产精品久久久久久久久久| 亚洲影院污污.| 国产欧美精品va在线观看| 久久9热精品视频| 麻豆精品网站| 一区二区精品在线| 国产精品一区二区三区久久 | 欧美大尺度在线观看| 99综合视频| 国产亚洲福利一区| 久久综合色影院| 999亚洲国产精| 久久久久国内| 一本久久综合| 国产欧美一区二区精品婷婷| 久久久久这里只有精品| 亚洲美女精品久久| 久久久久久成人| av成人福利| 黄色一区三区| 国产精品扒开腿做爽爽爽视频| 欧美一区综合| 日韩视频在线播放| 欧美中文在线观看| 日韩一级不卡| 国产一区二区视频在线观看 | 免费亚洲一区| 亚洲欧美另类国产| 亚洲片在线观看| 久久九九国产精品| 亚洲网在线观看| 亚洲国产福利在线| 国产欧美日韩不卡| 欧美日韩免费观看一区二区三区 | 含羞草久久爱69一区| 欧美日韩久久精品| 老司机精品视频网站| 亚洲欧美国产日韩天堂区| 亚洲日本va午夜在线电影| 久久夜色精品一区| 亚洲欧美日韩直播| 日韩写真视频在线观看| 在线观看视频日韩| 国产亚洲免费的视频看| 国产精品激情| 欧美日韩国产一中文字不卡| 久久影视精品| 香蕉免费一区二区三区在线观看| 亚洲精品自在久久| 亚洲国产精品一区| 欧美国产日韩一区二区三区| 久久久亚洲欧洲日产国码αv| 亚洲视频在线播放| 一本一本a久久| 亚洲精品小视频在线观看| 在线观看视频一区二区| 黄色日韩精品| 韩国女主播一区二区三区| 国产毛片一区| 国产精品一区一区| 国产女主播一区二区| 国产精品视频最多的网站| 国产精品美女久久久| 国产精品久久久久秋霞鲁丝| 欧美特黄一级大片| 国产精品激情av在线播放| 欧美性事在线| 国产精自产拍久久久久久| 国产精品资源| 国际精品欧美精品| 影音先锋久久| 亚洲精品在线视频| 亚洲视频每日更新| 亚洲一级片在线看| 欧美在线1区| 久久久亚洲国产美女国产盗摄| 久久婷婷国产综合精品青草| 久久在线视频在线| 欧美福利电影网| 亚洲精品一级| 亚洲一区二区精品| 久久国内精品自在自线400部| 久久久噜噜噜久久中文字幕色伊伊 | 久久在线观看视频| 亚洲国产导航| 99热这里只有成人精品国产| 亚洲桃色在线一区| 欧美在线视频一区二区三区| 久久躁狠狠躁夜夜爽| 欧美日韩另类字幕中文| 国产精品普通话对白| 一区视频在线看| 一区二区三区 在线观看视频| 亚洲一区二区三区三| 久久久久久91香蕉国产| 亚洲黑丝一区二区| 亚洲制服av| 欧美激情1区| 国产美女诱惑一区二区| 亚洲欧洲三级电影| 午夜免费久久久久| 亚洲高清免费视频| 午夜精品久久久久久99热软件| 美玉足脚交一区二区三区图片| 欧美体内谢she精2性欧美| 狠狠爱综合网| 亚洲欧美国产高清| 欧美激情片在线观看| 亚洲欧洲av一区二区| 欧美电影免费观看高清完整版| 国产女人精品视频| 99国产一区| 美日韩在线观看| 亚洲一区二区免费看| 欧美激情一区二区三区| 国产午夜精品全部视频播放| 一区二区国产精品| 欧美激情国产高清| 欧美在线亚洲一区| 国产精品福利在线观看| 亚洲啪啪91| 麻豆免费精品视频| 欧美一区高清| 国产女人18毛片水18精品| 亚洲图片欧美日产| 亚洲精品一区二区在线| 欧美/亚洲一区| 亚洲国产一区在线| 免费不卡亚洲欧美|