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

來源:互聯網
上載者:User

聲明:下面的執行個體全部在linux下嘗試,window下未嘗試。有興趣者可以試一下。文章針c初學者。
c語言的強符號和弱符號是c初學者經常容易犯錯的地方。而且很多時候,特別是多人配合開發的程式,它引起的問題往往非常行為怪異而且難以定位。
什麼是強符號和弱符號?
在c語言中,函數和初始化的全域變數是強符號,未初始化的全域變數時弱符號。強符號和弱符號的定義是連接器用來處理多重定義符號的,它的規則是:
不允許多個強符號;
如果一個強符號和一個弱符號,這選擇強符號;
如果多個弱符號,則任意選一個。
它的陷阱:
上代碼: 複製代碼 代碼如下://main.c
#include <stdio.h>
int fun();
int x;
int main()
{
printf("in main.c:x=%p\n", &x);
fun();
return 0;
}
//test.c
#include <stdio.h>
int x;
int fun()
{
printf("in test.c:x=%p\n", &x);
return 0;
}

編譯:gcc main.c test.c,運行,結果:
in main.c:x=0x80496a8
in test.c:x=0x80496a8
兩個x是一個變數。這也許可以說的過去,可能一個忘記加extern了。
再看:複製代碼 代碼如下://main.c
#include <stdio.h>
int fun();
int x;
int main()
{
printf("in main.c:&x=%p\n", &x);
fun();
return 0;
}

複製代碼 代碼如下://test.c
#include <stdio.h>
struct
{
<span style="white-space:pre"> </span>char a;
<span style="white-space:pre"> </span>char b;
<span style="white-space:pre"> </span>char c;
<span style="white-space:pre"> </span>char d;<span style="white-space:pre"> </span>

複製代碼 代碼如下:<span style="white-space:pre"> </span>int t;

複製代碼 代碼如下:} x;
int fun()
{
printf("in test.c:&x=%p\n", &x);
return 0;
}

運行結果:
in main.c:&x=0x80496e0
in test.c:&x=0x80496e0
連接器還認為他們是一個變數,這個時候程式員非常可能認為他們是兩個變數(或者說優秀的程式員會)。而事實卻相反,同一塊記憶體,在不同的檔案中會有不同的類型和含義。這兩個檔案對這塊記憶體讀寫的過程中,都會影響到對方,引發非常詭異的問題。
設想一下,如果是一個程式同時又多個人員來開發,如果他們只有有一個全域變數重名,且沒有初始化,那麼就會引發問題了。
在一個程式中出現問題還算好,畢竟代碼都在一起。如果你使用的動態庫或者靜態庫中有未初始化的全域變數,並且恰好也和你定義的重名,結果如何?我嘗試過,和上面一樣,衝突的兩個變數地址也相同。而這個時候你如果沒有庫的源碼,當發生了問題,變數被修改,你估計要走很多彎路才能想到是庫改了你的變數。這是我曾經解決過的一個問題。從那之後,我要求我們公司所有庫的源碼中不可以出現非static全域變數。
如何避免?
1、上策:想辦法消除全域變數。全域變數會增加程式的耦合性,對他要控制使用。如果能用其他的方法代替最好。
2、中策:實在沒有辦法,那就把全域變數定義為static,它是沒有強弱之分的。而且不會和其他的全域符號產生衝突。至於其他檔案可能對他的訪問,可以封裝成函數。把一個模組的資料封裝起來是一個好的實踐。
3、下策:把所有的符號全部都變成強符號。所有的全域變數都初始化,記住,是所有的。如果一個沒有初始化,就可能會和其他人產生衝突,儘管別人初始化了。(自己寫代碼測試一下)。
4、必備之策:GCC提供了一個選項,可以檢查這類錯誤:-fno-common。
c語言為什麼設計它?
容易引發問題,怎麼回事C的一個特性?可能是曆史的原因,沒有深究。但我認為也可能是部分語言設計哲學的原因:c語言的設計哲學有一點就是充分的相信程式員,給他們最大的權利和靈活性。這個特性在某些特殊的情況下也許可能發揮作用。
語言中的君子和小人:
古人說要近君子,遠小人。像今天說的這個特性(共同體也可以算一個),應該是c語言中的“小人”(輕拍,可能說的比較重)。我們還是敬而遠之的比較好。康熙好像說過,(特殊時期)治國不但要用君子,還要會用小人,但要能夠駕馭得當。否則會引火燒身。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.