函式名, 有初值的全域性變數, 編譯器會把它作為"強"符號,
而無初值的全域性變數, 編譯器會把它作為"弱"符號.
鏈結的時候, 如果不同檔案中出現同名的"強"符號, 鏈結失敗.
如果同名的有乙個"強"符號, 多個弱符號, 鏈結"強"符號, 丟棄"弱"符號.
如果只有多個同名的"弱"符號, 則隨機選乙個鏈入可執行檔案, 這也是有道理的, 因為反正沒有初值, 隨便選乙個就好了.
使用c程式用gcc驗證這一過程, 沒有問題, 但用c++程式, 以g++來編譯, 出現了符號多次定義的鏈結錯誤.
//檔案1:
int c;
int main (int argc, char const* argv)
//檔案2:
int c;
//檔案3:
int c:
問題出在編譯上, gcc遇到int c;全域性變數, 會把它作為common符號,是乙個"弱符號",
而g++在編譯c++程式時, 遇到 int c全域性變數, 會把它放在obj檔案的bss段裡, 是"強"符號, 所以就出現了強符號衝突的情況.
gcc, g++在編譯時, 對有非0初值的全域性int, 會放在data段, 而對0初值的全域性int, 會放在bss段, 放bss裡畢竟可以省可執行檔案的體積. 這一點沒區別.
但在處理沒寫初值的int時, 有了區別, 似乎g++會預設它初始化成0, 而gcc看它沒初始化就讓它common了.
C 原始檔包含C原始檔(C 中如何使用C)
如下 c語言標頭檔案 max.h ifndef max h define max h int max int na,int nb endif c語言實現檔案 max.c include max.h int max int na,int nb c 語言呼叫檔案 include max.h int tm...
C 關於標頭檔案和原始檔的分別
關於標頭檔案和原始檔的分別 首先,我們可以將所有東西都放在乙個.cpp檔案內.然後編譯器就將這個.cpp編譯成.obj,obj是什麼東西?就是編譯單元了.乙個程式,可以由乙個編譯單元組成,也可以有多個編譯單元組成.如果你不想讓你的源 變得很難閱讀的話,就請使用多個編譯單元吧.乙個函式不能放到兩個編譯...
C 關於標頭檔案和原始檔 編譯和鏈結問題
所有的標頭檔案,不會被編譯,include h的意義是 把某個標頭檔案的內容全部都搬進原始檔裡面。標頭檔案裡面不能 單獨宣告 乙個 int a char b 這種變數。因為在 include 後,會有多個定義。定義永遠只能有乙個,但是宣告可以有很多個。所以在鏈結後,如果多個cpp檔案 include...