使用“#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”而没有分配任何值——除了包括警卫之外?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取仅分配给一个值而没有其他值的唯一 ID 的计数?

为啥有时我可以分配双打而没有价值?

匹配数组项值并将新值分配给关联数组

不能将void*类型的值分配到int类型实体?

未初始化的值是由堆分配创建的:Unordered_map

PHP类与面向对象