編譯器版本
測試案例
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
void print(int a) //_Z5printi
{
}
double print(double,double,int,int) //_Z5printddii
{
return 0;
}
int print(int , int ,double,bool,char,short) //_Z5printiidbcs
{
return 0;
}
string print(string, int, int, string) //_Z5printNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiiS4_
{
return string();
}
int main()
{
return 0;
}
查看編譯之後函數符號變化
結論
C++函數重載機制其實是編譯器後面所做的name mangling,實際上所有的函數名字符號都不一樣,否則必定二義性(彙編中符號可以看做一個地址,如果不同作用的函數共用一個符合那麼只能說明這2個函數必然完全等同就是同一個)。並且我們也能夠從中窺探一番編譯器是如何對函數進行命名的,即:
_xx + 函數名稱 + 參數類型
並且我們可以得知如果是內置類型通常爲類型的首字母。如果是類,以標準庫string類爲例子,那麼會明確的指明到的是哪個具體的類,因爲標準庫中string的實現是十分複雜的,最終是指向一個名爲basic_string的類,因此後面那一大串的東西其實用於指明是string的最終依賴。並且函數命名與函數返回值毫無關係。
產生的問題
最明顯的就是C和C++混合編程時可能導致未定義的問題,因爲C函數編譯後的符號命名並不遵循C++編譯器的玩法,使用直接使用C函數會導致些問題。因此問了解決C函數在C與C++編譯器之間的共通需要如下聲明C函數:
#ifdef __cplusplus
extern "C"
{
#endif //__cplusplus
//C函數聲明或者定義
#ifdef __cplusplus
}
#endif //__cplusplus