__cdecl
__cdecl
是 C 和 C++ 程式的預設呼叫慣例。 由於堆疊已由呼叫端清除,所以它可以執行 vararg
函式。 呼叫 __cdecl
慣例會建立比 __stdcall 更大的可執行檔,因為它需要每個函式呼叫來包含堆疊清除程式碼。 下列清單會顯示這個呼叫慣例的實作。 修飾 __cdecl
詞是 Microsoft 特定的。
元素 | 實作 |
---|---|
引數傳遞順序 | 由右至左。 |
堆疊維護責任 | 呼叫函式會從堆疊取出引數。 |
名稱裝飾慣例 | 底線字元 (_) 前面會加上名稱,但匯出使用 C 連結的__cdecl函式除外。 |
大小寫轉譯慣例 | 未執行大小寫轉譯。 |
注意
如需相關資訊,請參閱 裝飾名稱 。
將 __cdecl
修飾詞放在變數或函式名稱之前。 因為 C 命名和呼叫慣例是預設值,因此您必須 __cdecl
在 x86 程式碼中使用的唯一時間是指定 /Gv
(vectorcall)、 /Gz
(stdcall) 或 /Gr
(fastcall) 編譯器選項。 /Gd 編譯器選項會 __cdecl
強制呼叫慣例。
在 ARM 和 x64 處理器上, __cdecl
會接受,但編譯器通常會忽略。 ARM 和 x64 的慣例會盡可能在暫存器中傳遞引數,並在堆疊上傳遞後續的引數。 在 x64 程式碼中,使用 __cdecl
來覆寫 /Gv 編譯器選項,並使用預設的 x64 呼叫慣例。
對於非靜態類別函式,如果函式是以非正規的方式定義,則不需要在非正規定義上指定呼叫慣例修飾詞。 也就是說,對於類別非靜態成員方法而言,宣告時所指定的呼叫慣例是在定義時假設。 如果已指定此類別定義:
struct CMyClass {
void __cdecl mymethod();
};
這個:
void CMyClass::mymethod() { return; }
相當於這個:
void __cdecl CMyClass::mymethod() { return; }
為了與舊版相容, 除非指定編譯器選項 /Za (停用語言延伸模組), 否則 cdecl 和 _cdecl 是同 __cdecl
義字。
範例
在下列範例中,編譯器收到的指示是針對 system
函式使用 C 命名及呼叫慣例。
// Example of the __cdecl keyword on function
int __cdecl system(const char *);
// Example of the __cdecl keyword on function pointer
typedef BOOL (__cdecl *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應