編譯器編譯源**生成目標檔案時,需要為每乙個變數、函式生成符號,儲存到符號表。在符號表中,每乙個符號必須唯一,因此要求源**中不能存在與其它檔案中的變數名、函式名相同的函式,包括使用到的庫中的函式。
為了解決符號名衝突的問題,編譯器會對源**中的符號進行修飾,如unix下編譯生成的符號會在符號名前加下劃線」_」。
一些高階語言如c++,則需要更為複雜的方式進行符號修飾。
比如c++支援函式過載,因此同乙個函式名可能具有多個不同的函式簽名。另外函式和變數還可能在不同的類中,也可以認為是不同的命名空間。
不同的編譯器的符號修飾規則不同,因此不同編譯器生成的目標檔案無法進行鏈結。在gcc編譯器中,c++的符號修改規則為:
以_z開關,如果有命名空間或類,則後面跟n,後面是命名空間或類名稱的長度,加上它的名稱,然後是函式的名稱的長度及函式名稱;如果前面有n,則加上字母e,然後是引數型別列表。
示例如下:
int func(int): _z4funci
double func(float): _z4funcf
void c::func(int, float): _z1c4funceif
從上面可以看到,c++的名字修飾規則與c不同,如果在c++**中使用了c的目標檔案,需要通知編譯器對這些符號採用c的名字修飾規則。即我們常見的**:
#ifdef __cplusplus
extern 「c」
#endif
這樣,編譯器在為int func(int)函式生成符號名時,就會採用c的符號修飾規則。
增加__cplusplus巨集判斷的原因是c編譯器不支援extern 「c」語法。
編譯器的函式名修飾規則
函式的名字修飾 decorated name 就是編譯器在編譯期間建立的乙個字串,用來指明函式的定義或原型。link程式或其他工具有時需要指定函式的名字修飾來定位函式的正確位置。多數情況下程式設計師並不需要知道函式的名字修飾,link程式或其他工具會自動區分他們。當然,在某些情況下需要指定函式的名字...
編譯器規則
類似這樣的錯誤 c program files microsoft visual studio 10.0 vc atlmfc include afxver h 81 fatal error c1189 error please use the md switch for afxdll builds。...
C和C 編譯器的函式名修飾規則
c編譯器的函式名修飾規則 對於 stdcall呼叫約定,編譯器和鏈結器會在輸出函式名前加上乙個下劃線字首,函式名後面加上乙個 符號和其引數的位元組數 例如 functionname number。cdecl呼叫約定僅在輸出函式名前加上乙個下劃線字首 例如 functionname。fastcall呼...