/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++ 成员函数、名为主功能的函数、带有 vararg 变量参数列表的函数或者标记有冲突的 __cdecl、 __stdcall 或 __fastcall 属性的函数)指定了 __vectorcall 调用约定。 此调用约定只能用于支持 /arch:SSE2 及以上的 x86 和 x64 体系结构,而对于面向 ARM 体系结构的编译器,将忽略此调用约定。

参数个数可变的函数必须标记为 __cdecl。

/Gd/Gr/Gv/Gz/clr:safe/clr:pure 不兼容。

备注

对于 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 命名约定使用前面带“at”符 (@) 的函数名,后跟函数参数大小(以字节为单位)。 不执行任何大小写转换。 编译器使用此命名约定模板:

@function_name@number

当您使用 __fastcall 命名约定时,请使用标准包含文件。 否则,您将获取无法解析的外部引用。

__stdcall 细节

__stdcall 函数的参数被从右到左推送到堆栈上,被调用函数在返回之前从堆栈中弹出这些参数。

对于 C,__stdcall 命名约定使用前面带下划线 (_) 的函数名,后跟“at”符 (@) 和函数的参数大小(以字节为单位)。 不执行任何大小写转换。 编译器使用此命名约定模板:

_functionname@number

__vectorcall 特定

__vectorcall 函数的整数参数由值传递,共使用两个(在 x86 上)或四个(在 x64 上)整数寄存器,六个浮点和检测值 XMM 寄存器,剩下的参数在堆栈上从右向左传递。 所调用的函数会在返回之前清理堆栈。 在 XMM0 中返回向量和浮点返回值。

对于 C,__vectorcall 命名约定使用后跟两个“at”符 (@@) 的函数名以及函数参数大小(以字节为单位)。 不执行任何大小写转换。 编译器使用此命名约定模板:

functionname@@number

请参见

参考

编译器选项

设置编译器选项