/Gd、/Gr、/Gv、/Gz(调用约定)
这些选项确定函数参数推送到堆栈中的顺序、调用函数或被调用函数是否在调用结束时从堆栈中删除参数,以及编译器用于标识各个函数的名称装饰约定。
语法
/Gd
/Gr
/Gv
/Gz
备注
默认设置 /Gd
为除 C++ 成员函数和标记为 __stdcall、__fastcall 或 __vectorcall 的函数之外的所有函数指定 __cdecl 调用约定。
/Gr
为除 C++ 成员函数、名为 main
的函数以及标记为 __cdecl
、__stdcall
或 __vectorcall
的函数之外的所有函数指定 __fastcall
调用约定。 所有 __fastcall
函数都必须有原型。 此调用约定仅在面向 x86 的编译器中可用,在面向其他体系结构的编译器中被忽略。
/Gz
为除 C++ 成员函数、名为 main
的函数以及标记为 __cdecl
、__fastcall
或 __vectorcall
的函数之外的所有函数指定 __stdcall
调用约定。 所有 __stdcall
函数都必须有原型。 此调用约定仅在面向 x86 的编译器中可用,在面向其他体系结构的编译器中被忽略。
/Gv
为除 C++ 成员函数、名为 main
的函数、带有 vararg
变量参数列表的函数,或使用存在冲突的 __cdecl
、__stdcall
或 __fastcall
属性标记的函数之外的所有函数指定 __vectorcall
调用约定。 此调用约定仅在支持 /arch:SSE2 及更高版本的 x86 和 x64 体系结构上可用,并且被面向 ARM 架构的编译器忽略。
采用可变数量参数的函数必须标记为 __cdecl
。
/Gd
、/Gr
、/Gv
和 /Gz
与 /clr:safe
或 /clr:pure 不兼容。 “/clr:pure”和“/clr:safe”编译器选项在 Visual Studio 2015 中已弃用,并且在 Visual Studio 2017 和更高版本中不受支持。
注意
默认情况下,对于 x86 处理器,C++ 成员函数使用 __thiscall
。
对于所有处理器,显式标记为 __cdecl
、__fastcall
、__vectorcall
或 __stdcall
的成员函数使用指定的调用约定,前提是该函数在此体系结构上不会被忽略。 采用可变数量参数的成员函数始终使用 __cdecl
调用约定。
这些编译器选项对 C++ 方法和函数的名称修饰没有影响。 除非声明为 extern "C"
,否则 C++ 方法和函数使用其他名称修饰方案。 有关详细信息,请参阅修饰名。
有关调用约定的详细信息,请参阅调用约定。
__cdecl 详细信息
在 x86 处理器上,所有函数参数都从右向左传递到堆栈上。 在 ARM 和 x64 体系结构上,某些参数通过寄存器进行传递,其余参数从右向左传递到堆栈上。 调用例程从堆栈中弹出参数。
对于 C,__cdecl
命令约定使用以下划线 ( _
) 开头的函数名称;不执行任何大小写转换。 除非声明为 extern "C"
,否则 C++ 函数使用其他名称修饰方案。 有关详细信息,请参阅修饰名。
__fastcall 详细信息
__fastcall
函数的某些参数在寄存器中传递(针对 x86 处理器、ECX 和 EDX),其余参数从右向左推送到堆栈上。 所调用的例程在返回之前从堆栈中弹出这些参数。 通常情况下,/Gr 可减少执行时间。
注意
为采用内联程序集语言编写的任何函数使用 __fastcall
调用约定时,请务必小心。 使用寄存器可能与使用编译器产生冲突。
对于 C,__fastcall
命名约定使用以 符号开头、后跟函数参数大小(字节)的函数名称@。 不执行任何大小写转换。 编译器将此模板用于命名约定:
@function_name@number
使用 __fastcall
命名约定时,请使用标准包含文件。 否则,会出现无法解析的外部引用。
__stdcall 详细信息
__stdcall
函数的参数从右向左推送到堆栈上,所调用的函数在返回之前从堆栈中弹出这些参数。
对于 C,__stdcall
命名约定使用以下划线 (_) 开头、后跟 @ 符号和函数参数大小(字节)的函数名称。 不执行任何大小写转换。 编译器将此模板用于命名约定:
_functionname@number
__vectorcall 详细信息
__vectorcall
函数的整数参数通过值传递,最多使用两个(在 x86 上)或四个(在 x64 上)整数寄存器,最多将六个 XMM 寄存器用于浮点和向量值,其余的参数从右向左传递到堆栈上。 被调用的函数在返回之前清除堆栈。 向量和浮点返回值在 XMM0 中返回。
对于 C,__vectorcall
命名约定使用后跟两个 符号和函数参数大小(字节)的函数名称@@。 不执行任何大小写转换。 编译器将此模板用于命名约定:
functionname@@number
在 Visual Studio 开发环境中设置此编译器选项
打开项目的“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性。
选择“配置属性”>“C/C++”>“高级”属性页。
修改“调用约定”属性。
以编程方式设置此编译器选项
- 请参阅 CallingConvention。