1

I'm trying to understand Steinberg's VST SDK.

What's the use of this:

#define PLUGIN_API 

without assiging any value in a header file and then PLUGIN_API occurring in many member functions' declarations/definitions for example like this:

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

Can someone explain this? The only use of #define without assigning a value that I know so far is using it as include guard.

Thank you in advance!

McNail
  • 100
  • 8

3 Answers3

3

What's the use of this:

#define PLUGIN_API 

Of this particular line, none really. Basically to allow compilation of other parts of code, of functions declarations, where this macro is used. Without defining it to empty, other parts of code could error when compiling.

like this:

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

Sure, so PLUGIN_API expands to nothing and is useless. However, someone might later compile the code for windows into a dll. To make a symbol visible in dll, one would have to go through all function declarations and add the proper specifier to them:

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

Or with the define just do:

#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
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • The question is asking about the case where `PLUGIN_API` is specifically defined as empty. – Acorn Jan 13 '21 at 10:21
  • 1
    Well, I edited to maybe make it more specific, but I believe this answer answers that question. It's empty, because it may not be empty... like in different environment. So it's empty because in this environment nothing is needed. – KamilCuk Jan 13 '21 at 10:32
  • My point is that this answer is about conditional compilation (which are, of course, the most common scenario), not about truly empty macros. – Acorn Jan 13 '21 at 10:36
2

It can be used as annotations that other tools may use.

For instance, I've seen it used in code generators, binding generators, static analysis tools, automated documentation generators, reflection systems, serialization systems, etc.

It could also serve as plain documentation for the user, but that is rare.

Acorn
  • 24,970
  • 5
  • 40
  • 69
  • 2
    in Qt its keywords are defined to be empty so that it can be built with a normal compiler, and then those keywords will be picked up by the MOC to generate other related code – phuclv Jan 13 '21 at 10:09
1

It also enables your to code later in the same translation unit some conditional compilation with #ifdef PLUGIN_API ... #endif. For the human reader of such C++ code, it serves as a useful annotation.

For more explanations, see this C++ reference and Stroustrup's book: Programming in C++.

For an example of tool related to such preprocessing, see GNU autoconf with GNU automake

For an example of C++ software using similar tricks, see Qt & FLTK

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547