使用没有赋值的“#define FOO”——除了包含守卫?

Use of "#define FOO" with no value assigned - other than as include guard?

我正在尝试了解 Steinberg 的 VST SDK。

这个有什么用:

#define PLUGIN_API 

没有在头文件中分配任何值,然后 PLUGIN_API 出现在许多成员函数中 declarations/definitions 例如:

Steinberg::tresult PLUGIN_API initialize (Steinberg::FUnknown* context) SMTG_OVERRIDE;
Steinberg::tresult PLUGIN_API terminate () SMTG_OVERRIDE;

有人可以解释一下吗?到目前为止,我所知道的唯一没有分配值的#define 用法是将它用作包含保护。

提前致谢!

它可以用作其他工具可能使用的注释。

例如,我看到它用于代码生成器、绑定生成器、静态分析工具、自动文档生成器、反射系统、序列化系统等

它也可以作为用户的简单文档,但这种情况很少见。

它还使您可以稍后在同一个翻译单元中使用 #ifdef PLUGIN_API ... #endif 进行一些条件编译。对于这种 C++ 代码的人类 reader,它可以作为一个有用的注释。

更多解释见this C++ reference and Stroustrup's book: Programming in C++.

有关此类预处理的工具示例,请参见GNU autoconf with GNU automake

有关使用类似技巧的 C++ 软件示例,请参阅 Qt & FLTK

What's the use of this:

#define PLUGIN_API 

关于这一行,none 真的。基本上允许编译代码的其他部分,函数声明,其中使用了这个宏。如果不定义为空,其他部分代码在编译时可能会出错。

like this:

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