日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++函数名的修饰规则

發布時間:2023/11/30 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++函数名的修饰规则 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們知道在C++中有函數重載這樣一個東西,當我們定義了幾個功能類似且函數名是一樣的函數的時候,只要它的參數列表不同,編譯是可以通過的,但是在C中是不可以的。

?


double add(double a, double b)
{
? ? return a + b;
}

int add(int a, char b)
{
? ? return a + b;
}
char add(char a, char b)
{
? ? return a + b;
}

?

如果這樣寫的代碼,在C中會報出errorC2371,說是add函數重定義。但是如果在C++環境下這樣是允許的,叫做函數的重載,只要你的幾個函數符合函數重載的要求,是完全沒有問題的。這就引出了在C和C++中函數名的修飾規則,為什么在C 中就是不行的?

?

???????

double add(double a, double b);
//{
// return a + b;
//}

?

我把這個函數的定義改為聲明,然后在main函數中調用,就可以看到提示中的

?

1. C編譯器的函數名修飾規則?

編譯器給我們報出了一個鏈接錯誤,可以看到_add這樣的函數,這就是在C環境下編譯器對我們函數名的修飾,可以看到是在函數的前面加上下劃線,當然這種修改實在默認調用約定__cdecl的情況下,如果在__stdcall調用約定,編譯器和鏈接器會在輸出函數名前加上一個下劃線前綴,函數名后面加上一個“@”符號和其參數的字節數,__fastcall調用約定在輸出函數名前加上一個“@”符號,后面也是一個“@”符號和其參數的字節數。

???我們可以修改一下調用約定,看看是不是這樣的。

??

???這樣修改之后再看看,可以看到add函數被修飾為_add@16.所以在不同調用約定下修飾規則也是有所不同的。

???

1. C++編譯器的函數名修飾規則?

然后,再看看在C++環境下,編譯器對我們的函數是怎樣修飾的:

????????可以看到,對于我聲明的double add(double a,double b)函數,被修飾為?(?add@@YANNN@Z),可以看到,這和在C環境中是完全不一樣的,所以這也是在C++中有函數重載的原因,那么來看看這到底是怎么修飾的。

?

???????C++的函數名修飾規則有些復雜,但是信息更充分,通過分析修飾名不僅能夠知道函數的調用方式,返回值類型,參數個數甚至參數類型。不管__cdecl,__fastcall還是__stdcall調用方式,函數修飾都是以一個“?”開始,后面緊跟函數的名字,再后面是參數表的開始標識和按照參數類型代號拼出的參數表。對于__stdcall方式,參數表的開始標識是“@@YG”,對于__cdecl方式則是“@@YA”,對于__fastcall方式則是“@@YI”。參數表的拼寫代號如下所示:?
X--void????
D--char????
E--unsigned char????
F--short????
H--int????
I--unsigned int????
J--long????
K--unsigned long(DWORD)?
M--float????
N--double????
_N--bool?
U--struct?

?????可以看到N是代表double類型,那么?(?add@@YANNN@Z)就能理解了,函數修飾符?,接著是函數名字,然后是_cdecl約定的開始標示符@@YA然后連著的是返回值類型,參數列表的參數類型剛好是,那么double add(double a,double b)就是NNN,參數表后以“@Z”標識整個名字的結束,如果該函數無參數,則以“Z”標識結束。

????還有當參數列表有指針的時候,指針的方式有些特別,用PA表示指針,用PB表示const類型的指針。后面的代號表明指針類型,如果相同類型的指針連續出現,以“0”代替,一個“0”代表一次重復。

????舉一個簡單的例子: int fun(int *p1, int *p2);

????

???可以看到,我的fun函數被修飾為(?fun@@YAHPAH0@Z)。

???還有在C++中的成員函數中公有和私有的成員函數的修飾也有相應的表示符。總而言之,在C++環境中的函數名修飾的時候,會帶有參數列表的信息,還有返回值的信息,所以在C++中的函數重載就是允許存在的,因為它可以根據你的參數列表選擇對應的函數,而顯然在我們的C環境下是不允許的。

?
————————————————
原文鏈接:https://blog.csdn.net/mr_listening/article/details/51472184

總結

以上是生活随笔為你收集整理的C++函数名的修饰规则的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。