Strange multiple class names in Linderdaum Engine - c++

I am trying to use Linderdaum Engine and found there many strange declarations like:
class scriptfinal netexportable ClassName: public iObject
These strange names scriptfinal and netexportable are macros. But they are defined to be empty.
Why someone can need this kind of defines?

They're empty so that the C++ compiler won't care about them.
The Linderdaum Engine preprocesses the C++ sources in order to generate meta-information about the classes.
Those macros are most likely used by their preprocessor to generate information for their scripting language (scriptfinal) and .NET serialization code (netexportable).

For example, someone might set the scriptfinal macro to:
#define scriptfinal __declspec(dllimport)
to get:
class __declspec(dllimport) ClassName: public iObject {};
Since __declspec is a Microsoft specific extension so normally it is used by macro expansion in portable code. When compiling for the Linux environment the macros are empty so __declspec is not visible to the compiler and under Windows they will be defined as above.

Related

A strange C++ class declaration

Have read this thread in stackoverflow: Strange class declaration
, but still confused with below code in foo.h:
class Foo CHECKLEAKDCL {
I am sure that Foo should be the class name, since there are constructor and deconstructor which can imply this.
I cannot see any macro definition related with CHECKLEAKDCL in this .h file.
also I am confused with the answer for Strange class declaration , which saying that:
Q_CORE_EXPORT isn't an identifier. It's a platform-dependent macro,
and it's used to signal a class that's intended to be used across
library boundaries.
Can anyone give some more explanation of this?
UPDATE:
found this line in a .h file, which is included in foo.h:
#define CHECKLEAKDCL : private CheckLeak
so the class declarition should be :
class Foo : private CheckLeak {
So Foo is extending CheckLeak, right?
If you compile for windows (using Visual Studio), highly possible it will be evaluated to one of the Microsoft specific linkage identifiers, dllexport or dllimport :
https://msdn.microsoft.com/en-us/library/81h27t8c.aspx
It is used when you create a class which will be exported from a DLL or used from a DLL in an application, and dependig of this it's either evaluated to dllexport (DLL exporting the class) or dllimport (Application importing the class).
If you compile with GCC possibly it will evaluate to one of the gcc _-attribute__s. Such as __attribute__ ((visibility ("default"))) (https://gcc.gnu.org/wiki/Visibility)
These extensions to the core C++ are provided by compilers to make certain tasks more easily achievable (https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Extensions.html)
EDIT
After you updated the answer ... well, obviously you have a private inheritance from a class. But please note, this is a terrible macro you have there because
#define CHECKLEAKDCL : private CheckLeak
adds an : in your class declaration so you cannot use that symbol anymore to inherit from base classes.
I'd recommend that you get rid of that macro altogether, if you cannot, do not use it, it will confuse your code.
We cannot tell exactly what it is, as we have even less information than you do.
Normally, I have seen such macros resolve to export macro, for the library.
That is, the value of it should be defined as dllexport, dllimport or extern (depending on platform). When that is the case though, the macro appears before the class name.
Considering the macro appears after the class name, it can only resolve to a base class, or list of base classes, or an empty macro.
If you have the documentation, search for a base class that tracks or reports it's address to a memory tracker on construction and destruction.
Then, the code base should be compiled using a macrodefinition similar to this:
#define CHECKLEAKDCL() : private MemoryTrackingBaseClass
(where MemoryTrackingBaseClass is the class I mentioned above - according to your edit, CheckLeak).
If you want to simply compile, try using:
#define CHECKLEAKDCL()
Edit (addressing your update)
So Foo is extending CheckLeak, right?
Only when you want to check your application for leaks, using whatever CheckLeak implements.
In a production environment (after you use the definition inheriting from CheckLeak), you should probably define CHECKLEAKDCL as an empty macro (for speed).
As you've discovered, CHECKLEAKDCL is a macro that expands to the three tokens : private CheckLeak. Presumably CheckLeak is a class that adds some leak checking diagnostic behaviour to classes which inherit from it.
In general, this sort of obfuscation is not very helpful. Depending on the properties of CheckLeak, this macro might have unintended side effects, such as turning what appears to be a standard layout class into a non-standard layout class.
It would also be hard to add CHECKLEAKDCL to a class that wanted to inherit from another class for any other reason. (Are you supposed to class Foo CHECKLEAKDCL, public OtherBase ?)
Personally, if given the chance to improve this project I'd favour replacing this macro with its actual expansion in this case.

C++ Pre-processor define after class keyword and before class name

I recently came across this sort of code in someone's opengl shader class and am not sure of its use.
As I understand it from reading IBM's documentation, the #define ONEWORD will remove any occurence of ONEWORD in the subsequent text.
What is the purpose of having ONEWORD in this code at all if all occurrences are removed? What does having a token like that, after a class keyword but before a class name, really mean?
I've only used #define for include guards in the past so this is entirely new for me.
#define ONEWORD
class ONEWORD FooClass
{
FooClass();
~FooClass();
};
The code I saw this in is here: https://dl.dropbox.com/u/104992465/glsl.h
Just in case I've made its context too abstract.
It's to allow you to easily add compiler specific keywords to your class declaration. For instance with Visual Studio, if you wanted to put this class in a DLL, you would change your definition to
#define ONEWORD __declspec( dllexport )
See here for another example
Oh, so after looking at the actual code, it's not ONEWORD, but rather GLSAPI. These XYZ_API macros are often used for conditionally specifying platform-specific linkage, such as some __attributes__ which require different treatment on, for example, Windows and Unixes. So you can expect GLSAPI to be defined in one of the header files (maybe in config.h) like this:
#ifdef WIN32
# define GLSAPI __dllimport
#elif defined __linux__
# define GLSAPI __attribute__((visibility("visible")))
#else
# define GLSAPI
#endif
(Pseudo-code, I'm not sure about all the attributes and linkage "qualifiers", but you can look them up in the code.)

What does it mean when a class declaration appears to have two names?

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.

Pointless 'MIDL_INTERFACE' Macro in winapi?

After browsing some old code, I noticed that some classes are defined in this manner:
MIDL_INTERFACE("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")
Classname: public IUnknown {
/* classmembers ... */
};
However, the macro MIDL_INTERFACE is defined as:
#define MIDL_INTERFACE(x) struct
in C:/MinGW/include/rpcndr.h (somewhere around line 17). The macro itself is rather obviously entirely pointless, so what's the true purpose of this macro?
In the Windows SDK version that macro expands to
struct __declspec(uuid(x)) __declspec(novtable)
The first one allows use of the __uuidof keyword which is a nice way to get the guid of an interface from the typename. The second one suppresses the generation of the v-table, one that is never used for an interface. A space optimization.
This is because MinGW does not support COM (or rather, supports it extremely poorly). MIDL_INTERFACE is used when defining a COM component, and it is generated by the IDL compiler, which generates COM type libraries and class definitions for you.
On MSVC, this macro typically expands to more complicated initialization and annotations to expose the given C++ class to COM.
If I had to guess, it's for one of two use cases:
It's possible that there's an external tool that parses the files looking for declarations like these. The idea is that by having the macro evaluate to something harmless, the code itself compiles just fine, but the external tool can still look at the source code and extract information out of it.
Another option might be that the code uses something like the X Macro Trick to selectively redefine what this preprocessor directive means so that some other piece of the code can interpret the data in some other way. Depending on where the #define is this may or may not be possible, but it seems reasonable that this might be the use case. This is essentially a special-case of the first option.

What is __declspec and when do I need to use it?

I have seen instances of __declspec in the code that I am reading. What is it? And when would I need to use this construct?
This is a Microsoft specific extension to the C++ language which allows you to attribute a type or function with storage class information.
Documentation
__declspec (C++)
The canonical examples are __declspec(dllimport) and __declspec(dllexport), which instruct the linker to import and export (respectively) a symbol from or to a DLL.
// header
__declspec(dllimport) void foo();
// code - this calls foo() somewhere in a DLL
foo();
(__declspec(..) just wraps up Microsoft's specific stuff - to achieve compatibility, one would usually wrap it away with macros)
It is mostly used for importing symbols from / exporting symbols to a shared library (DLL). Both Visual C++ and GCC compilers support __declspec(dllimport) and __declspec(dllexport). Other uses (some Microsoft-only) are documented in the MSDN.
Another example to illustrate the __declspec keyword:
When you are writing a Windows Kernel Driver, sometimes you want to write your own prolog/epilog code sequences using inline assembler code, so you could declare your function with the naked attribute.
__declspec( naked ) int func( formal_parameters ) {}
Or
#define Naked __declspec( naked )
Naked int func( formal_parameters ) {}
Please refer to naked (C++)
Essentially, it's the way Microsoft introduces its C++ extensions so that they won't conflict with future extensions of standard C++. With __declspec, you can attribute a function or class; the exact meaning varies depending on the nature of __declspec. __declspec(naked), for example, suppresses prolog/epilog generation (for interrupt handlers, embeddable code, etc), __declspec(thread) makes a variable thread-local, and so on.
The full list of __declspec attributes is available on MSDN, and varies by compiler version and platform.
I know it's been eight years but I wanted to share this piece of code found in MRuby that shows how __declspec() can bee used at the same level as the export keyword.
/** Declare a public MRuby API function. */
#if defined(MRB_BUILD_AS_DLL)
#if defined(MRB_CORE) || defined(MRB_LIB)
# define MRB_API __declspec(dllexport)
#else
# define MRB_API __declspec(dllimport)
#endif
#else
# define MRB_API extern
#endif