使用“#define FOO”而没有分配任何值——除了包括警卫之外?
Posted
技术标签:
【中文标题】使用“#define FOO”而没有分配任何值——除了包括警卫之外?【英文标题】:Use of "#define FOO" with no value assigned - other than as include guard? 【发布时间】:2021-01-13 09:57:00 【问题描述】:我正在尝试了解 Steinberg 的 VST SDK。
这个有什么用:
#define PLUGIN_API
不分配头文件中的任何值,然后在许多成员函数的声明/定义中出现 PLUGIN_API,例如:
Steinberg::tresult PLUGIN_API initialize (Steinberg::FUnknown* context) SMTG_OVERRIDE;
Steinberg::tresult PLUGIN_API terminate () SMTG_OVERRIDE;
有人能解释一下吗?到目前为止,#define 没有分配值的唯一用途是将其用作包含保护。
提前谢谢你!
【问题讨论】:
github.com/skiselkov/libacfutils/blob/master/SDK/CHeaders/XPLM/… 【参考方案1】:这个有什么用:
#define PLUGIN_API
在这一行中,真的没有。基本上允许编译使用此宏的代码的其他部分,函数声明。如果不将其定义为空,则其他部分代码在编译时可能会出错。
像这样:
Steinberg::tresult PLUGIN_API initialize (Steinberg::FUnknown* context) SMTG_OVERRIDE; Steinberg::tresult PLUGIN_API terminate () SMTG_OVERRIDE;
当然,所以PLUGIN_API
扩展为空且无用。但是,以后可能有人将 windows 的代码编译成 dll。要使符号在 dll 中可见,必须通过 all 函数声明并向它们添加适当的说明符:
Steinberg::tresult __declspec(dllexport) initialize (Steinberg::FUnknown* context) SMTG_OVERRIDE;
Steinberg::tresult __declspec(dllexport) terminate () SMTG_OVERRIDE;
或者用定义来做:
#if I_AM_COMPILING_ON_WINDOWS_FOR_A_DLL
#define PLUGIN_API __declspec(dllexport)
#else
#define PLUGIN_API /* nothing needed */
// defining PLUGIN_API to be empty, allows code to compile with no additional work
#endif
【讨论】:
问题是询问PLUGIN_API
具体定义为空的情况。
好吧,我进行了编辑以使其更具体,但我相信这个答案回答了这个问题。它是空的,因为它可能不是空的……就像在不同的环境中一样。所以它是空的,因为在这种环境中什么都不需要。
我的意思是,这个答案是关于条件编译(当然,这是最常见的场景),而不是真正的空宏。【参考方案2】:
它可以用作其他工具可能使用的注释。
例如,我已经看到它用于代码生成器、绑定生成器、静态分析工具、自动文档生成器、反射系统、序列化系统等。
它也可以作为用户的简单文档,但这种情况很少见。
【讨论】:
在Qt中它的关键字被定义为空,这样就可以用普通的编译器来编译,然后这些关键字会被MOC提取出来生成其他相关的代码【参考方案3】:它还允许您稍后在同一翻译单元中使用#ifdef PLUGIN_API
... #endif
进行一些条件编译。对于此类 C++ 代码的人类读者来说,它是一个有用的注释。
更多解释见this C++ reference和Stroustrup的书:Programming in C++.
有关此类预处理的工具示例,请参阅GNU autoconf 和GNU automake
有关使用类似技巧的 C++ 软件示例,请参阅 Qt 和 FLTK
【讨论】:
以上是关于使用“#define FOO”而没有分配任何值——除了包括警卫之外?的主要内容,如果未能解决你的问题,请参考以下文章