Name Mangling
Name Mangling》又稱為《Name Decoration》目的讓各個overloaded function有一個獨有的辨認名稱。
C語言中沒有所謂的overloaded function,所以C Compiler不會產生任何的Name Mangling資訊。
C++語言中提供overloaded function,所以C++ Compiler在編譯時,會產生functionName Mangling
以提供LinkerLink函式或程式庫時,能適當的選者出所使用的overloaded function
Name Mangling沒有一套共同的規則,每個廠牌的compiler會有不同的Name Mangling規則,但目的是一樣的。
先以一個程式來說明Linker的概念及Name Mangling,先建立以下的檔案,並放置在同一個專案中:
【作者使用之
Compiler:Visual C++ 6.0
code:

//專案名稱:Name_Mangling
//檔案1MyFun.h
#include<stdio.h>
void MyFun();
//檔案2MyFun.c
void MyFun()
{
	printf("MyFun() in C file\n");
}
//檔案3CPP_MAIN.cpp
#include <iostream>
#include "MyFun.h"
using namespace std;
int main()
{
	MyFun();
	return 0;
}

編譯(Compile)後之資訊:
--------------------Configuration: Name_Mangling - Win32 Debug--------------------
Compiling...
Skipping... (no relevant changes detected)
CPP_MAIN.CPP

CPP_MAIN.OBJ - 0 error(s), 0 warning(s)

連結
(Link)後之資訊:
--------------------Configuration: Name_Mangling - Win32 Debug--------------------
Compiling...
MyFun.C
c:\...\myfun.c(3) : warning C4013: 'printf' undefined; assuming extern returning int
Linking...
CPP_MAIN.OBJ : error LNK2001: unresolved external symbol "void __cdecl MyFun(void)" (?MyFun@@YAXXZ)
Debug/Name_Mangling.exe : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

Name_Mangling.exe - 2 error(s), 1 warning(s)
(
專案名稱 )

現在來說明這個為什麼會出現《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.objMyFun()Symbol為《?MyFun@@YAXXZ

3.LinkerLinkCPP_MAIN.obj函式MyFun()Symbol?MyFun@@YAXXZ》時
找不到同樣為?MyFun@@YAXXZ》的Symbol,所以無法resolve(解析)Linker會產生
如以下的錯誤訊息:
unresolved external symbol "void __cdecl MyFun(void)" (?MyFun@@YAXXZ)

從以上得知,C++需提供一個方法來解決C CompilerC++ 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
Hosted by www.Geocities.ws

1