參考《程式設計師的自我修養》main.c參考 c語言中的強符號與弱符號
int a = 100;
int main()
other.c
int a = 10;
編譯
gcc main.c other.c
編譯結果
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1
multiple definition of `a'
這種符號的定義可以被稱為強符號(strong symbol)注意下面的函式,初始化了的全域性變數為強符號
未初始化的全域性變數為弱符號
__attribute__((weak))
是gcc提供的將強符號轉為弱符號的關鍵字
main.c
extern int ext;
int weak1;
int strong = 1;
int __attribute__((weak)) weak2 = 2;
int main()
test.c
int weak1 = 100;
//int strong = 100; //multiple definition of `strong'
int weak2 = 200;
編譯gcc mainc test.c
結果
100,100,200
這裡有人會將強符號理解為extern,因為在mainc和test.c兩個模組中共享全域性變數,你可以列印位址(位址是一樣的)。關於定義與宣告的區別,請看這篇文章c語言的定義與宣告但兩者是本質不同的
extern 本質就是宣告變數,告訴linker去其他模組找定義。
而強符號和弱符號可是實打實的定義。雖然我們說弱符號沒有初始化。
說實話,我也是看了《程式設計師的自我修養》之後,才知道有強符號和弱符號的概念,而且在mac上試了一下,不行,只能在gun linux上玩。看了各個廠商在這方面的實現出入還很大!結論
如果去掉test.c中strong的定義,就會報"重複定義"錯誤。首先,從上面的例子可以看到,兩個模組共享變數。但是又和extern不同,extern就是宣告,完全沒有分配記憶體。但是這裡可是定義,照樣共享記憶體了!
例子1weak.c
void __attribute__((weak)) f();
int main(void)
編譯
gcc weak.c
結果
通過了,並且還能執行!很奇怪吧
例子2增加乙個f.c
#include void f(void)
編譯
gcc weak.c f.c
結果
hello from f
例子3修改weak.c
#include void __attribute__((weak)) f()
int main(void)
編譯
gcc weak.c
結果
hello from weak
編譯
gcc weak.c f.c
結果
hello from f
注意
編譯方式不同,結果不同
結論根據上面三個例子,得到結論:
例1,只有弱符號f,編譯通過!沒有報reference f not defined!
例2,3 f.c是強符號,結果執行結果用的是f.c中的f定義
最後乙個例子4
main.c
#include #include extern int fun(void);
int global_var1 = 0xff00ff00; // 強符號
int main(int argc, const char *ar**)
test.c
#include #include #include double global_var1;
int fun(void)
結論 C語言中的強符號與弱符號問題
弱符號與強符號 對於c c 語言來說,編譯器預設函式和初始化了的全域性變數為強符號,未初始化的全域性變數為弱符號。我們也可以通過gcc的 attribute weak 將乙個強符號變為弱符號。強符號和弱符號都是針對定義來說的,不是針對符號的引用。extern int ext int weak 弱符號...
C語言中的強符號和弱符號
c語言中的強符號和弱符號 c語言真的很奇怪,各種你想不到的問題都會出現,但是仔細分析這個問題,無不很有道理,這些都不是c語言的漏洞,而是這門語言的強大之處。首先介紹一下強符號和弱符號。當多個c檔案需要一起編譯執行的時候,就會有強弱符號的問題。為什麼會有多個c檔案一起編譯呢?這就的說起鏈結linkin...
C語言中的強符號和弱符號介紹
之前在extern c 用法詳解中已經提到過符號的概念,它是編譯器對變數和函式的一種標記,編譯器對c和c 在生產符號時規則也是不一樣的,符號除了本身名字的區別外,還有強符號和弱符號之分 我們先看一段簡單的 複製 如下 test.c void hello int main 很顯然,這段 是沒法鏈結通過...