我正在使用visual studio处理现有的c ++项目,并且我发现几乎每个函数声明都在函数名前面获得__cdecl
,例如:void __cdecl functionName()
。然后我跳转到__cdecl
的定义,该定义位于winnt.h
文件中:
#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define NTAPI __stdcall
#else
#define _cdecl
#define __cdecl
#define NTAPI
#endif
我已经搜索过cdecl并认为它是C和C ++程序的默认调用约定,但上面的代码告诉我__cdecl
没有扩展。那么为什么在功能名称之前放置一个__cdecl
,因为它什么都没有?还是我误解了上面的代码?
答案 0 :(得分:0)
#define __cdecl“
的含义是什么
以#
开头的行是预处理程序指令。 #define
是一个定义预处理器宏的指令。 #define __cdecl
定义了一个标识为__cdecl
且空替换的宏。如果定义了这样的宏,处理器将用空字符串替换__cdecl
的所有实例。
那么为什么在函数名之前放置一个__cdecl,因为它什么都没有?
查看相关定义开头的指令:
#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) #else
宏定义为有条件。未定义宏时,__cdecl
不会扩展为空。如果没有扩展为空,__cdecl
是您发现的微软特定函数说明符。
条件定义的宏允许用户编写在允许它的系统上使用__cdecl
的代码,并在不支持它的系统上自动删除它。
但我仍然对#if(_MSC_VER> = 800)||感到困惑定义(_STDCALL_SUPPORTED)行,它是什么意思?
它是一个预处理程序指令,用于测试宏_MSC_VER
的值是否大于800,或者是否定义了宏_STDCALL_SUPPORTED
。如果测试为假,则删除#if和#else之间的代码。如果是,则删除#else和#endif之间的代码。
答案 1 :(得分:0)
这意味着如果将API定义为使用NTAPI,它将生成使用__stdcall调用约定的代码 - Pascal调用约定的变体,其中被调用者清理堆栈。使用__cdecl,调用者清理堆栈(因此它支持可变参数类型函数)。
所有这些都取决于#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)