__cdecl

Microsoft 专用

__cdecl 是 C 和 C++ 程序的默认调用约定。 由于堆栈已由调用方清理,因此它可以执行 vararg 函数。 __cdecl 调用约定创建的可执行文件大于 __stdcall 调用约定创建的可执行文件,这是因为它要求每个函数调用包括堆栈清理代码。 以下列表显示此调用约定的实现。

元素

实现

参数传递顺序

从右到左。

堆栈维护职责

调用函数从堆栈中弹出参数。

名称修饰约定

下划线字符 (_) 作为名称的前缀,导出使用 C 链接的 __cdecl 函数时除外。

大小写转换约定

不执行任何大小写转换。

备注

有关相关信息,请参阅修饰名

将 __cdecl 修饰符放置在变量或者函数名称的前面。 由于 C 命名和调用约定为默认值,因此你只能在指定 /Gv (vectorcall)、/Gz (stdcall) 或 /Gr (fastcall) 编译器选项时,在 x86 代码中使用 __cdecl。 /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; }

示例

在下面的示例中,将指示编译器对 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, ...);

请参见

参考

参数传递和命名约定

C++ 关键字