新手小心 c語言中強符號與弱符號的使用

2022-10-04 05:18:07 字數 1774 閱讀 3985

c語言的強符號和弱符號是c初學者經常容易犯錯的地方。而且很多時候,特別是多人配合開發的程式,它引起的問題往往非常行為怪異而且難以定位。

什麼是強符號和弱符號?

在c語言中,函式和初始化的全域性變數是強符號,未初始化的全域性變數時弱符號。強符號和弱符號的定義是聯結器用來處理多重定義符號的,它的規則是:

不允許多個強符號;

如果乙個強符號和乙個弱符號,這選擇強符號;

如果多個弱符號,則任意選乙個。

它的陷阱:

上**:

複製** **如下:

#include

int fun();

int x;

int main()

#include

int x;

int fun()

編譯:gcc main.c test.c,執行,結果:

in main.c:x=0x80496a8

in test.c:x=0x804程式設計客棧96a8

兩個x是乙個變數。這也許可以說的過去,可能乙個忘記加exterbyexxiivfn了。

再看:複製** **如下:

#include

int fun();

int x;

int main()

複製** **如下:

#include

struct

x;int fun()

執行結果:

in main.c:&x=0x80496e0

in test.c:程式設計客棧&x=0x80496e0

聯結器還認為他們是乙個變數,這個時候程式設計師非常可能認為他們是兩個變數(或者說優秀的程式設計師會)。而事實卻相反,同一塊記憶體,在不同的檔案中會有不同的型別和含義。這兩個檔案對這塊記憶體讀寫的過程中,都會影響到對方,引發非常詭異的問題。

設想一下,如果是乙個程式同時又多個人員來開發,如果他們只有有乙個全域性變數重名,且沒有初始化,那麼就會引發問題了。

在乙個程式**現問題還算好,畢竟**都在一起。如果你使用的動態庫或者靜態庫中有未初始化的全域性變數,並且恰好也和你定義的重名,結果如何?我嘗試過,和上面一樣,衝突的兩個變數位址也相同。而這個時候你如果沒有庫的原始碼,當發生了問題,變數被修改,你估計要走很多彎路才能想到是庫改了你的變數。這是我曾經解決過的乙個問題。從那之後,我要求我們公司所有庫的原始碼中不可以出現非static全域性變數。

如何避免?

1、上策:想辦法消除全域性變數。全域性變數程式設計客棧會增加程式的耦合性,對他要控制使用。如果能用其他的方法代替最好。

2、中策:實在沒有辦法,那就把全域性變數定義為static,它是沒有強弱之分的。而且不會和其他的全域性符號產生衝突。至於其他檔案可能對他的訪問,可以封裝成函式。把乙個模組的資料封裝起來是乙個好的實踐。

3、下策:把所有的符號全部都變成強符號。所有的全域性變數都初始化,記住,是所有的。如果乙個沒有初始化,就可能會和其他人產生衝突,儘管別人初始化了。(自己寫**測試一下)。

4、必備之策:gcc提供了乙個選項,可以檢查這類錯誤:-fno-common。

c語言為什麼設計它?

容易引發問題,怎麼回事c的乙個特性?可能是歷史的原因,沒有深究。但我認為也可能是部分語言設計哲學的原因:c語言的設計哲學有一點就是充分的相信程式設計師,給他們最大的權利和靈活性。這個特性在某些特殊的情況下也許可能發揮作用。

語言中的君子和小人:

古人說要近君子,遠小人。像今天說的這個特性(共同體也可以算乙個),應該是c語言中的「小人」(輕拍,可能說的比較重)。我們還是敬而遠之的比較好。康熙好像說過,(特殊時期)治國不但要用君子,還要會用小人,但要能夠駕馭得當。否則會引火燒身。

本文位址:

C語言中的強符號與弱符號

參考 程式設計師的自我修養 參考 c語言中的強符號與弱符號 main.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...

C語言中的強符號與弱符號問題

弱符號與強符號 對於c c 語言來說,編譯器預設函式和初始化了的全域性變數為強符號,未初始化的全域性變數為弱符號。我們也可以通過gcc的 attribute weak 將乙個強符號變為弱符號。強符號和弱符號都是針對定義來說的,不是針對符號的引用。extern int ext int weak 弱符號...

C語言中的強符號和弱符號

c語言中的強符號和弱符號 c語言真的很奇怪,各種你想不到的問題都會出現,但是仔細分析這個問題,無不很有道理,這些都不是c語言的漏洞,而是這門語言的強大之處。首先介紹一下強符號和弱符號。當多個c檔案需要一起編譯執行的時候,就會有強弱符號的問題。為什麼會有多個c檔案一起編譯呢?這就的說起鏈結linkin...