我一直在阅读stdio.h文件,我很困惑。
例如,有这一行:
_CRTIMP FILE* __cdecl __MINGW_NOTHROW fopen (const char*, const char*);
我知道“FILE *”表示返回类型,我发现_CRTIMP是常量定义为
# ifndef _CRTIMP
# define _CRTIMP __declspec(dllimport)
# endif
但我还是不明白它,它的用途是什么?什么是其余的字符串(__ cdecl,__ MINGW_NOTHROW)?
答案 0 :(得分:5)
__declspec(dllimport)
指定从单独的dll导入该函数;我想,根据CRT静态/动态链接设置,它以不同的方式定义。
__cdecl
是用于该函数的调用约定;调用约定告诉编译器函数如何被调用(在哪个顺序参数被推入堆栈,如果任何寄存器用于参数,存储返回值,谁负责堆栈清理,... );一般来说,只要你不写图书馆就不用担心。
__MINGW_NOTHROW
是#define
d扩展为__attribute__ ((__nothrow__))
,这是一个特定于MinGW的扩展,告诉编译器该函数不会抛出异常;这让编译器可以执行一些优化。
请注意,所有这些都不是标准C属性,而是编译器/平台特定的东西。同样,一般来说你不应该担心它们,它们需要使CRT工作正常,但只要你不构建库,你就可以在不知道它们的情况下逃脱。 :)
答案 1 :(得分:5)
您应该查看_mingw.h
和gcc manual:如果是gcc - 或任何其他支持__GNUC__
的编译器 - 以下定义适用:
#define __cdecl __attribute__ ((__cdecl__))
#define __MINGW_NOTHROW __attribute__ ((__nothrow__))
前者告诉编译器使用cdecl x86调用约定(see gcc manual),后者保证函数不会抛出C ++异常(see gcc manual)。
__declspec(dllimport)
是动态链接工作所必需的(see gcc manual)。
答案 2 :(得分:1)
__declspec(dllimport)
告诉编译器需要从DLL导入此函数,它是Windows特定的扩展。有关详细信息,请参阅this page。
同样,__cdecl
是一个属性,它指定函数使用特定的调用约定(即C使用的约定)。请参阅this page。
我猜想__MINGW_NOTHROW宏是GCC nothrow
属性的同义词,它告诉编译器有问题的函数不能抛出异常。有关详细信息,请参阅documentation。
答案 3 :(得分:0)
这些是特定于您正在使用的环境或编译器的声明。
__declspec(dllimport)
在Windows上表示此函数在dll中,应该放在生成的可执行PE文件的导入表中。__cdecl
表示标准C调用约定,并将修改编译器转换函数以符合此调用约定的方式。 __MINGW_NOTHROW
特定于您的编译器,可能会取消激活对异常的支持。在所有情况下,编译器的文档中都必须有解释。