#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
// How to determine the identifier above?
// Where did `MATHLIBRARY_API` came from?
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif
Another example:
#ifdef BUILD_DLL
// same question here.where BUILD_DLL came from?
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
I'm working on making a header file for a DLL, and I'm really stuck on this.
I'm confused about what identifier I should use after #ifdef
or #ifndef
directives.
Asking where MATHLIBRARY_API
comes from seems incongruous, as it's defined right there in the code.
I suspect you're actually asking about using MATHLIBRARY_EXPORTS
instead, since you later asked about BUILD_DLL
(which is also a using case). So I'll base this answer on that.
Definitions typically happen in one of two places:
#define
earlier in the process. You can see that in operation in your code where it defines, for example, DLL_EXPORT
.-D MATHLIBRARY_EXPORTS
.In terms of the actual names you can use, these are identifiers so have to follow certain rules set down in the standard(1).
You are also responsible for managing "collisions" of those names between individual parts of the compilation process (such as your code and third-party code). So, if two header files that you use each had different definitions for TRUE, that could cause issues:
#define TRUE 1
#define TRUE (!0)
As an example of using this (very similar to your MATHLIBRARY_EXPORTS/MATHLIBRARY_API
example, I suspect), see the following code:
#ifdef ACCESS_PRIVATE
# define PRIVATE
#else
# define PRIVATE static
#endif
void public_function() { /* code goes here */ }
PRIVATE void private_function() { /* code goes here */ }
If you compile that with g++ -c -o file.o file.c
, then private_function()
will be static, so not visible outside of the current translation unit.
However, if you added -D ACCESS_PRIVATE
to the compiler flags, then the function would not be static and you would be able to access it from other code that you link.
This sort of thing is often done for unit tests of otherwise private functions.
(1) For allowable characters in identifiers, see the current iteration of the standard at time of this answer, C++20 5.10 Identifiers
(or equivalent section in other iterations).
This is functionally defined as having the first character drawn from the set (C allows for extra implementation-defined characters, C++ apparently does not):
[A-Za-z]
._
.\U0001f602
being 😂. However, keep in mind certain universal characters (such as combining characters) are disallowed in the first position of an identifier.That character is then followed by zero or more subsequent characters which are either:
[0-9]
.