探討為什么CPP支持函式多載而C不支持?
- Windows作業系統下VS編譯C檔案
- Windows作業系統下VS編譯CPP檔案
- Linux作業系統下gcc編譯C檔案
- Linux作業系統下g++編譯CPP檔案
Windows作業系統下VS編譯C檔案
#include <stdio.h>
#include <Windows.h>
double add(double a, double b);
int main()
{
add(1.0, 2.0);
system("pause");
return 0;
}
這段代碼編譯可以通過,但是鏈接通過不了
報錯:
錯誤 2 error LNK2019: 無法決議的外部符號 _add,該符號在函式 _main 中被參考
#include <stdio.h>
#include <Windows.h>
int add(int a, int b);
int main()
{
add(1, 2);
system("pause");
return 0;
}
這段代碼可以通過編譯階段,但是無法通過鏈接階段
報錯:
錯誤 2 error LNK2019: 無法決議的外部符號 _add,該符號在函式 _main 中被參考
由上述兩個相同功能但資料型別不同的add函式的報錯可以看出:add函式在編譯之后存在符號表中的名字都是_add,而main函式名字是_main
所以,
VS編譯器編譯C檔案時對于相同名字的函式并不做區分
,都是以
_函式名
來命名
Windows作業系統下VS編譯CPP檔案
#include <iostream>
using namespace std;
int add(int a, int b);
double add(double a, double b);
int main()
{
add(1.0, 2.0);
add(1, 2);
system("pause");
return 0;
}
這段代碼可以通過編譯,但是不能通過鏈接
報錯:
error LNK2019: 無法決議的外部符號 “int __cdecl add(int,int)” (?add@@YAHHH@Z),該符號在函式 _main 中被參考
error LNK2019: 無法決議的外部符號 “double __cdecl add(double,double)” (?add@@YANNN@Z),該符號在函式 _main 中被參考
由報錯可以看出:自定義函式的函式名經過編譯之后,變成了另外一種表現形式,對于同名函式有區分度
命名規則:【?函式名@@YA回傳值資料型別對應字母+形參資料型別對應字母@Z】
對應關系:
- int -> H
- double-> N
- float -> M
- char -> D
- void -> X
- bool -> _N
例如:
int add(int ,int ) -> ?add@@YAHHH@Z
double func(double,double) -> ?func@@YANNN@Z
Linux作業系統下gcc編譯C檔案

由此可以看出gcc編譯c之后,自定義函式的函式名不變,對于同名函式沒有區分度,
Linux作業系統下g++編譯CPP檔案

由此可以看出g++編譯CPP檔案之后,自定義函式的函式名改變了,可以對同名函式進行區分,
命名規則:【_Z + 函式名字長度 + 函式名 + 形參資料型別首字母】
例如:
int add(int ,int ) -> _Z 3 add i i
int func(double ,double ,double) -> _Z 4 func d d d
總結:無論是Windows作業系統還是Linux作業系統,基于這些作業系統的主流編譯器都有一下特點:
- 編譯C檔案: 編譯之后,對于 相同函式名的自定義函式 無區分度
- 編譯CPP檔案:編譯之后,對于 相同函式名的自定義函式 有區分度
結:無論是Windows作業系統還是Linux作業系統,基于這些作業系統的主流編譯器都有一下特點:
- 編譯C檔案: 編譯之后,對于 相同函式名的自定義函式 無區分度
- 編譯CPP檔案:編譯之后,對于 相同函式名的自定義函式 有區分度
因此,至于是 命名規則 導致 C語言不支持函式多載而CPP支持函式多載 ,還是 C語言不支持函式多載而CPP支持函式多載 導致 命名規則如此,其因果關系就仁者見仁智者見智啦
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/156100.html
標籤:其他
上一篇:最優化問題(一)
