Name Mangling
編譯(Compile)後之資訊:code:
//專案名稱:Name_Mangling //檔案1:MyFun.h #include<stdio.h> void MyFun();//檔案2:MyFun.c void MyFun() { printf("MyFun() in C file\n"); }//檔案3:CPP_MAIN.cpp #include <iostream> #include "MyFun.h" using namespace std; int main() { MyFun(); return 0; }
現在來說明這個為什麼會出現《unresolved external symbol》
1.在檔案MyFun.C中撰寫一個C語言的函式名為MyFun()
經過編譯之後所得之MyFun.obj檔中,會以一個Symbol來表示這個函式
一般C compiler會在函式名稱前加上"_"而組成所對應的Symbol
所以在MyFun.obj檔中,有一個Symbol為《_MyFun》
2.在程式CPP_MAIN.cpp中呼叫函式MyFun()
經過編譯之後得之CPP_MAIN.obj檔中,會以一個Symbol來表示所呼叫的函式
一般C++ compiler會依據不同的Name
Mangling Rule來產生所對應的Symbol
而VC++中所產生的Symbol為《?MyFun@@YAXXZ》
所以在CPP_MAIN.obj中MyFun()的Symbol為《?MyFun@@YAXXZ》
3.當Linker要Link在CPP_MAIN.obj函式MyFun()之Symbol《?MyFun@@YAXXZ》時
找不到同樣為《?MyFun@@YAXXZ》的Symbol,所以無法resolve(解析),Linker會產生
如以下的錯誤訊息:
《unresolved external symbol
"void __cdecl MyFun(void)"
(?MyFun@@YAXXZ)》
從以上得知,C++需提供一個方法來解決C
Compiler與C++
Compiler所產生Symbol之差異。
這個問題會在之後的文章《extern
"C"》做說明。
Name mangling主要是解決overloaded
function的問題,接下來看兩個overloaded
function:
int Sum(int num1,int num2)
{ return num1+num2; }
int Sum(int num1,int num2,int num3)
{ return num1+num2+num3; }
查看這兩個函式的Symbol:
"int __cdecl
Sum(int,int)" (?Sum@@YAHHH@Z)
"int __cdecl Sum(int,int,int)" (?Sum@@YAHHHH@Z)
在Symbol中會加上有關函式名稱、回傳型態、參數型態...等資訊,以提供Link時便於resolve。
以上的介紹希望有助於程式編譯時流程的概念。歡迎指教
Tips:
1.《依據Compiler的不同,有不同的指定方式》:英文稱為《Compiler-specific》
2.Overloaded function:函式具有相同名稱,有不同的參數列(Parameter
lists)
參考文獻:
1.C++
Name Mangling/Demangling
Written By James On 2004/04/30