UNIX連接器對強符號與弱符號的處理

      在編譯的時候,編譯器向彙編器輸出每一個全局符號,或是強(strong)或者弱(weak),而彙編器把這個信息隱含地編碼在可重定位目標文件的符號表裏,函數和已初始化的全局變量是強符號,未初始化的全局變量是弱符號。         根據強弱符號的定義,UNIX連接器使用下面的規則來處理多重定義的符號: 函數

            1.  不容許有多個強符號 編碼

            2. 若是有一個強符號,多個弱符號,那麼會選擇強符號 spa

            3. 若是有多個弱符號,那麼從這些弱符號中任選一個 編譯器

如下是幾個小例子: io

<1>       編譯

int main()                                              int main()                                              變量

{                                                          { di

       return 0;                                               return 0; 文件

}                                                          } co


連接器會提示強符號main被重複定義。


<2>   

/* foo2.c */                                               /* bar3 */

#include <stdio.h>                                int x;

void f();                                                 void f()

int x = 123;                                           {

int main()                                                      x = 132;

{                                                            }

    f();

    printf("x = %d\n", x);

    return 0;

}

    在運行時,函數f會將X的值改成132, 這會給main函數的使用者帶來不受歡迎的意外!!!注意,連接器一般不會代表它檢測到多個X的定義!!!

執行: ./foo

最後會輸出132

<3> 若是x是弱定義,也會發生相似2的問題

* foo2.c */                                               /* bar3 */

#include <stdio.h>                                int x;

void f();                                                 void f()

int x ;                                                 {

int main()                                                      x = 132;

{                                                            }

    x = 123;    

    f();

    printf("x = %d\n", x);

    return 0;

}

輸出x = 132


因此GCC有 -fno-common這個選項調用連接器,能夠在遇到多重定義的全局符號時給出warning

相關文章
相關標籤/搜索