首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C/C++ 調用約定全解析:__cdecl, __stdcall, __fastcall, __thiscall 區別與選擇

     編輯:關於C++

調用約定決定的五大要素

  1. 參數傳遞:寄存器 vs 棧。
  2. 參數壓棧順序:左→右 vs 右→左。
  3. 可變參數支持。
  4. 是否需要函數原型。
  5. 棧平衡責任:調用者 vs 被調用者。

主流約定對比表

約定參數傳遞壓棧順序棧平衡可變參數名字修飾典型用途
__cdecl棧右→左調用者支持_funcC/C++ 默認
__stdcall棧右→左被調用者不支持_func@NWin32 API
__fastcall前 2 個 DWORD 寄存器 (ECX,EDX),其餘棧右→左被調用者不支持@func@N高性能調用
__thiscallthis 指針 ECX,其餘棧右→左被調用者不支持編譯器內部C++ 非靜態成員函數
__vectorcall盡可能寄存器 (SIMD 向量)右→左被調用者不支持@@func@N向量運算優化

關鍵差異詳解

__cdecl(C Declaration)

  • 默認約定,支持可變參數(如 printf)。
  • 調用者清理棧 → 可變參數可行(調用者知曉參數大小)。
  • 名字修飾:前綴下劃線 _func。

__stdcall(Standard Call)

  • Windows API 標準(WINAPI 宏)。
  • 被調用者清理棧 → 固定參數個數,不支持可變參數。
  • 名字修飾:_func@字節數(如 _Func@8 表示 8 字節參數)。

__fastcall

  • 前兩個 DWORD 參數通過 ECX、EDX 傳遞,減少內存訪問。
  • 其餘參數右→左壓棧。
  • 名字修飾:@func@字節數。

__thiscall

  • C++ 成員函數默認(MSVC)。
  • this 指針放入 ECX,參數右→左壓棧。
  • 被調用者清理棧。

混合調用約定的陷阱

  • 函數指針類型必須匹配調用約定:void (__stdcall *fp)(int)。
  • DLL 導出函數建議統一用 __stdcall(或 extern "C" __stdcall 禁用名字修飾)。
  • 內聯彙編中手動管理棧需知曉約定細節。

現代建議

  1. 跨模塊(DLL/EXE)接口用 __stdcall + extern "C"。
  2. 內部高性能函數可用 __fastcall 或 __vectorcall。
  3. 避免在 C++ 類成員函數指針間轉換約定(類型系統會阻擋)。
  4. 64 位 Windows 只有**一種**約定(前 4 參數 RCX,RDX,R8,R9,其餘棧),上述 32 位差異不復存在。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved