Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macros in the middle of a class or function declaration

Tags:

c++

class

macros

I've read related questions like this and this, and other pages, but they don't really answer my question.

Basically, I see code like the following.

class SOME_MACRO SomeClass{
    SomeClass();
    ~SomeClass();
};

This is really confusing to me. Now I consider myself reasonably knowledgeable about C++ (though less so with the preprocessor), but I don't remember seeing declarations like that in any book I've read. However I see code like this in the real world all the time, for example in OpenCV. There seems to be a discrepancy between the C++ you learn about in a book or in class, and the C++ you actually see in practice, and I find that rather unfortunate.

I've learnt from here and here that macros like that above are used to tell the linker how to link it properly, or something like that. For the example here, the QuickFAST_Export gets turned into either __declspec(dllexport) or __declspec(dllimport). In other cases, these macros tell the linker how to behave depending on whether the system is Linux or Windows. I know all this from an abstract perspective; I know what the macros are there for and I know what they do now, roughly at least. So I don't want answers like "those macros are there so you can change the [...]", because those answers don't tell me how I might go about using this kind of declaration myself, in a program that I might write from scratch, myself.

My question is, since when was it legal to just put something like __declspec(dllimport) in the middle of a class declaration anyway? What actual thing is __declspec(dllimport)? An int? An object? In which part of the C++ standard does it say that class declarations like this are legal? If someone could write a minimal program illustrating a class declaration with a non-trivial (non-empty) macro in the middle of it, that compiles and preferably does something visible, that would be much appreciated.

like image 942
Ray Avatar asked Dec 18 '22 21:12

Ray


1 Answers

I've learnt from here and here that macros like that above are used to tell the linker how to link it properly, or something like that.

To be pedantic, it's not the macro that tells the linker how to link. The macro is simply replaced by the preprocessor by whatever text it's defined to be replaced with. In the case of your example, it would be conditionally replaced with __declspec(dllexport) or __declspec(dllimport). Those declspec specifiers on the other hand do tell the linker what to do... at least some linker that understands the specifier.

since when was it legal to just put something like __declspec(dllimport) in the middle of a class declaration anyway?

Since Microsoft implemented their compiler and specified that it's legal. It's not legal according to the c++ standard.

In which part of the C++ standard does it say that class declarations like this are legal?

It doesn't. Using those specifiers is non-standard and not guaranteed to work in any other compiler than Microsoft's. That's why such macro is typically defined to expand to an empty string (or possibly something else, specific to another implementation) when used in a compiler that does not support the keyword.

What actual thing is __declspec(dllimport)?

It is a non-standard keyword. You can find out more from their (Microsoft) documentation.

To dive a little bit deeper, the keywords tell the linker how to export symbols when compiling a shared (dynamically linked) library. Dynamic linking is a concept that's entirely foreign to the standard. It's implementation defined.

how I might go about using this kind of declaration myself, in a program that I might write from scratch, myself.

Do you intend to write a shared library? If not, then you don't need to know. If yes, then you need to read the documentation of every platform that you're targetting.

Here is a walkthrough in the Microsoft's documentation that guides you through the steps to create a dynamically linked library.

like image 168
eerorika Avatar answered Dec 24 '22 03:12

eerorika