2017-03-29 109 views
2

我正在使用visual studio處理現有的C++項目,並且我發現幾乎每個函數聲明都在函數名前面有一個__cdecl,如:void __cdecl functionName()。然後我跳到的__cdecl的定義,其定位在winnt.h文件:我的C++代碼中「#define __cdecl」的含義是什麼?

#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) 
#define NTAPI __stdcall 
#else 
#define _cdecl 
#define __cdecl 
#define NTAPI 
#endif 

我搜索cdecl,並得到了它的缺省調用C和C++程序慣例,但上面的代碼告訴我,__cdecl延伸到無所事事。那麼爲什麼在函數名稱之前放置一個__cdecl,因爲它什麼都沒有?還是我誤解了上面的代碼?

+1

的*編譯*條件對待'__cdecl'聲明。它不是(也不能)在語言中定義的,因此宏是空的。 –

+0

查看'#if'及其條件?如果這種情況是真的,那麼編譯器可能會把這些作爲擴展關鍵字。 –

+1

Microsoft編譯器使用'__cdecl'作爲調用約定。對於其他編譯器,它可以被定義爲什麼都不是。 –

回答

0

什麼的#define __cdecl」與#開頭的預處理指令

臺詞的意思。 #define是定義預處理器宏的指令。 #define __cdecl定義了一個宏,標識符爲__cdecl,爲空替換。如果定義了這樣的宏,處理器將用空字符串替換__cdecl的所有實例。

那麼爲什麼在函數名前放置__cdecl,因爲它什麼都沒有?

看看這些指令在定義的問題開始:

#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) 
#else 

宏定義有條件。宏未定義時,__cdecl不會擴展爲空。如果沒有擴展到無,__cdecl是您發現的微軟特定函數說明符。

有條件地定義的宏允許用戶在允許的系統上編寫使用__cdecl的代碼,並在不支持的系統上自動刪除它。

但我仍然困惑#if(_MSC_VER> = 800)||定義(_STDCALL_SUPPORTED)行,這是什麼意思?

這是一個預處理器指令,用於測試宏_MSC_VER是否具有大於800的值,或者是否定義了宏_STDCALL_SUPPORTED。如果測試是錯誤的,那麼#if和#else之間的代碼將被刪除。如果它是真的,那麼#else和#endif之間的代碼將被刪除。

+0

我明白了。所以這是在某些條件下評論'__cdecl'的一種方法。但是我仍然對#if(_MSC_VER> = 800)||產生困惑定義(_STDCALL_SUPPORTED)'行,這是什麼意思? – Mark

+0

@Mark查看編輯。 – user2079303

+0

@Mark:'_MSC_VER'僅由Microsoft Visual C編譯器定義,幷包含其版本號。如果編譯是在Microsoft編譯器(版本8或更高版本)上完成的,或者是聲明'_STDCALL_SUPPORTED'的編譯器,則這是一個檢查。他們將使用'__stdcall'和'__cdecl';其他編譯器不會。 – DevSolar

0

這意味着如果一個API被定義爲使用NTAPI,它將生成使用__stdcall調用約定的代碼 - 這是被調用者清除堆棧的Pascal調用約定的變體。使用__cdecl,調用者清除堆棧(因此它支持可變類型函數)。

而這一切是在#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)