I am reading a C++ header file, in which there writes:
class CLASSEXPORT skExecutable : {.....}
A comment says that CLASSEXPORT is a macro expansion and then I find where CLASSEXPORT is defined.
#define CLASSEXPORT
And that's all..I feel confused about this..What does CLASSEXPORT represent in this sense? And how to understand the class skExecutable?
In your case, CLASSEXPORT is expanded to nothing (probably because it is not needed to expand it into something meaningful in your exact configuration), so your class will just be a class skExecutable {<...>};. This approach is commonly used for import/export directives, e.g. in the following snippet an appropriate directive will be places depending on whether COMPILING_DLL macro is defined:
#if COMPILING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif
class DLLEXPORT MyClass
{
};
Just to clear some stuff up: CLASSEXPORT is a macro. Macro expansion is a process, performed prior to compilation, during which all macros are replaced with whatever they are defined as.
In your case, I suspect that CLASSEXPORT is there to allow all classes that are declared in that way to be exported to some kind of shared library if the need arises in the future. Then that CLASSEXPORT would be defined as something like
#define CLASSEXPORT __declspec(dllexport)
and you could use skExecutable directly from a shared library.
Related
I use a macro in C++ to switch between compiling logging or not:
#define MAYBE_LOG(msg)
#ifdef PRINT_MSGS
ALWAYS_LOG(msg)
#endif
How does the #define know where the ending is? The #endif refers to the #ifdef, not the #define.
#define ends at end of the line (which might be extended with final \)
The code in the question does two separate things: it defines a macro named MAYBE_LOG with no body and, if PRINT_MSGS is defined, it uses a macro named ALWAYS_LOG. If that's not what it's supposed to do, then, yes, it needs to be changed. Since the question doesn't say what the code is supposed to do, this is just a guess:
#ifdef PRINT_MSGS
#define MAYBE_LOG(msg) ALWAYS_LOG(msg)
#else
#define MAYBE_LOG(msg)
#endif
The reason for doing it this way (and not using \ on each line to extend the macro definition is that you can't put #if conditions inside the definition of a macro.
This question already has answers here:
Macros in the middle of a class or function declaration
(4 answers)
Closed 6 years ago.
I found the following code:
class BOOST_FILESYSTEM_DECL path
{
};
Usually a class is defined this way:
class Baloon
{
};
How can I have two terms in the class declaration? Does somebody knows what BOOST_FILESYSTEM_DECL is used for (boost library)?
If you take a look at how it is defined, all will be clear:
#ifdef BOOST_HAS_DECLSPEC // defined in config system
// we need to import/export our code only if the user has specifically
// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost
// libraries to be dynamically linked, or BOOST_FILESYSTEM_DYN_LINK
// if they want just this one to be dynamically liked:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_FILESYSTEM_DYN_LINK)
// export if this is our own source, otherwise import:
#ifdef BOOST_FILESYSTEM_SOURCE
# define BOOST_FILESYSTEM_DECL __declspec(dllexport)
#else
# define BOOST_FILESYSTEM_DECL __declspec(dllimport)
#endif // BOOST_FILESYSTEM_SOURCE
#endif // DYN_LINK
#endif // BOOST_HAS_DECLSPEC
//
// if BOOST_FILESYSTEM_DECL isn't defined yet define it now:
#ifndef BOOST_FILESYSTEM_DECL
#define BOOST_FILESYSTEM_DECL
#endif
As you can see, it is a macro. It expands to __declspec(dllexport) or __declspec(dllimport) or empty, depending on other macros. See this answer for more details about declspec specifier. In short, it is platform specific feature that is needed for dynamic linking.
It's actually a macro that evaluates to either __declspec(dllimport) or __declspec(dllexport), and it's basically being used by the Boost libraries to tell the compiler to export (for their own code) or import (for external code).
It is a macro; see here for the definition.
It controls the exposition of the class from the shared library (dll); basically it will land up being a __declspec() (or similar depending on the platform) for either the dllexport when building boost, or dllimport when used in client code.
The BOOST_FILESYSTEM_DECL is probably a macro, look for the declaration:
#define BOOST_FILESYSTEM_DECL
to see what it's mean.
According to cplusplus.com, the syntax to define a macro is:
#define identifier replacement
However, I sometimes stumble upon a macro definition which doesn't contain a replacement. For example in afxwin.h, there is the following preprocessor definition:
#define afx_msg // intentional placeholder
My questions:
What happens at compile-time when a preprocessor definition that doesn't have a replacement is used? Is it simply ignored? For example, does the line afx_msg void OnAddButton(); become void OnAddButton();?
What is the purpose of using preprocessor without replacement? Is it simply to make code more clear?
"Nothing" (no text) is a valid replacement text for a macro. It will simply be removed (more precisely, replaced by nothing) by the preprocessor.
There are multiple reasons why you'd use something like this. One is to simply use the macro in #ifdef and similar constructrs.
Another is conditional compilation. A typical use case is public APIs and DLL exports. On Windows, you need to mark a function as exported from a DLL (when building the DLL) or as imported from a DLL (when linking against the DLL). On ELF systems, no such declarations are necessary. Therefore, you'll often see code like this in public library headers:
#ifdef _WIN32
#ifdef BUILDING_MYLIB
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
#else
#define MYLIB_API
#endif
void MYLIB_API myApiFunction();
Yet another reason could be code processing tools. Perhaps you have a tool which parses source code, extracting a list of functions with a certain marker. You can define such a marker as an empty macro.
#define bla
simply defines bla.
you can use it with
#ifdef bla
...
place some code here
...
#endif
a typical use case is #define DEBUG to enable special code parts in debugging mode.
Another way to set such things from "outside" is:
g++ -DDEBUG x.cpp
which also sets the macro DEBUG defined.
And every header file should have something like:
#ifndef THIS_HEADER_INCLUDE_GUARD
#define THIS_HEADER_INCLUDE_GUARD
...
rest of header file
...
#endif
This simply protects your header file for (recursivly) read more the once.
Some can be done with implementation specific #pragma once.
the preprocessor processes it, removing it and replacing it with nothing
could be a variety of reasons, including readability, portability, custom compiler features, etc.
I'm trying to understand some C++ code which has the following class syntax:
class Q_MONKEY_EXPORT BasePlugin : public QObject
{
// some code comes here
};
I cannot understand the syntax class Q_MONKEY_EXPORT BasePlugin. To me it looks like if there are two names for the class. What exactly does this kind of syntax mean in C++?
Q_MONKEY_EXPORT is most likely a #define somewhere. Defines like that are sometimes required, for example when the class is in a library and needs to be exported when the header file is included from somewhere else. In that case, the define resolves to something like __declspec(dllexport) (the exact syntax will depend on the tools you are using).
That's most probably a preprocessor directive telling the compiler the symbol is to be exported.
It's probably defined as:
#define Q_MONKEY_EXPORT _declspec(dllexport)
which will cause your class to be exported to the dll.
The full declaration will be expanded, before compilation, to:
class _declspec(dllimport) BasePlugin : public QObject
{
// some code comes here
};
EDIT:
As David Heffernan pointed out, macros like these are generally used to let the compiler know whether it needs to import or export the symbols. Usually defined as dllimport for outside modules and dllexport when building the module. I doubt that's the case here, since the name suggests exporting, but it's best to check the documentation or actually go to the definition.
Q_MONKEY_EXPORT is a macro (all upper case is convention for macro) that typically resolves to something like __declspec(dllexport) when you are building the DLL and resolves to __declspec(dllimport) when you are using the DLL.
You can find out exactly what it is by reading your include files.
I found this in Ogre Framework
class _OgreSampleClassExport Sample_Character : public SdkSample {
...
...
and it's define like this
#define _OgreSampleClassExport
Why we want to have this macro variable?
Presumably so a special qualifier, such as __declspec(dllexport), could be added to such classes by modifying (or conditionally defining) the define:
#define _OgreSampleClassExport __declspec(dllexport)
It's to allow for future exports. Ogre may just strictly be a statically linked library at the moment, but if the authors ever decide to support dynamically-linked libraries (aka shared libraries on some platforms), they will need to write code like:
class
#ifdef EXPORTING
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
Sample_Character [...]
... and that's just for MSVC. Normally they'd have to go through the effort to do this to Sample_Character and all other classes they provide through their library. Making a single macro to be defined later is much easier as they'll only need to do this in one place.