在編譯的時候,編譯器向彙編器輸出每一個全局符號,或是強(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