【问题标题】:Meaning of declaration of function函数声明的含义
【发布时间】:2011-02-16 12:30:44
【问题描述】:

我一直在阅读stdio.h 文件,我很困惑。

比如有这样一行:

_CRTIMP FILE* __cdecl __MINGW_NOTHROW fopen (const char*, const char*);

我知道FILE*表示返回类型,我发现_CRTIMP是常量,定义为

# ifndef _CRTIMP
#  define _CRTIMP  __declspec(dllimport)
# endif

我不明白,它有什么用?其余的字符串是什么(__cdecl__MINGW_NOTHROW)?

【问题讨论】:

    标签: c function definition


    【解决方案1】:

    __declspec(dllimport) 指定函数要从单独的dll中导入;我想,根据 CRT 静态/动态链接设置,它的定义方式不同。

    __cdecl 是函数的调用约定;调用约定告诉编译器函数期望如何被调用(参数被压入堆栈的顺序,如果任何寄存器用于参数,返回值的存储位置,谁负责堆栈清理,...... );一般来说,只要您不编写库,您就不必担心它。

    __MINGW_NOTHROW#defined 扩展为__attribute__ ((__nothrow__)),这是一个MinGW 特定的扩展,告诉编译器该函数不会抛出异常;这让编译器可以执行一些优化。

    请注意,所有这些都不是标准的 C 属性,而是编译器/平台特定的东西。同样,一般来说,您不必担心它们,它们是使 CRT 正常工作所必需的,但只要您不构建库,您就可以在不了解它们的情况下逃脱。 :)

    【讨论】:

      【解决方案2】:

      您应该查看_mingw.hgcc 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)。

      【讨论】:

        【解决方案3】:

        __declspec(dllimport) 告诉编译器该函数需要从 DLL 导入,它是 Windows 特定的扩展。详情请见this page

        同样,__cdecl 是一个属性,它指定函数使用特定的调用约定(即 C 使用的约定)。见this page

        我猜想 __MINGW_NOTHROW 宏是 GCC nothrow 属性的同义词,它通知编译器相关函数不能抛出异常。详情请见documentation

        【讨论】:

          【解决方案4】:

          这些是特定于环境或您正在使用的编译器的声明。

          • __declspec(dllimport) 在 Windows 上表示该函数位于 dll 中,应放在生成的可执行 PE 文件的导入表中。
          • __cdecl 表示标准 C 调用约定,并将修改编译器转换函数的方式以符合此调用约定。
          • __MINGW_NOTHROW 特定于您的编译器,可能会停用对异常的支持。

          在任何情况下,编译器的文档中都必须有说明。

          【讨论】:

            猜你喜欢
            • 2022-11-25
            • 2011-07-27
            • 2020-07-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-10-28
            • 1970-01-01
            相关资源
            最近更新 更多