宏在类或函数声明的中间 [英] Macros in the middle of a class or function declaration

查看:74
本文介绍了宏在类或函数声明的中间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读过相关问题,例如 this this 和其他页面,但他们不'

基本上,我看到如下代码。

 <$> c $ c> class SOME_MACRO SomeClass {
SomeClass();
〜SomeClass();
};

这真的让我很困惑。现在我认为自己相当了解C ++(虽然不如预处理器那么),但我不记得在我读过的任何书中看到这样的声明。但是,我在所有的时间都在现实世界中看到这样的代码,例如在 OpenCV 。你在书中或课堂上学到的C ++和实际上看到的C ++之间似乎存在差异,我发现这是相当不幸的。



我已从此处在这里,像上面的宏用于告诉链接器如何链接它正确,或类似的东西。对于此处的示例 QuickFAST_Export 变成 __ declspec(dllexport) __ declspec(dllimport)。在其他情况下,这些宏告诉链接器如何行为取决于系统是Linux还是Windows。我从一个抽象的角度了解这一切;我知道什么宏有什么,我知道他们现在做什么,大致至少。所以我不想要的答案像那些宏,所以你可以改变[...],因为这些答案不告诉我如何使用这种声明自己,在一个程序,我可能会从头开始写自己。



我的问题是,因为什么时候合法的只是把 __ declspec(dllimport)在类声明的中间?实际上是什么是 __ declspec(dllimport) int ?一个东西?在C ++标准的哪一部分,它说这样的类声明是合法的?如果有人可以写一个最小的程序来说明一个类声明,在它的中间有一个非平凡的(非空)宏,它编译,最好做一些可见的事情,这将是非常感激。

解决方案


我从这里和这里学到了类似上面的宏用于告诉链接器如何正确链接,


为了让人踩踏,不是告诉链接器如何链接。宏被预处理器简单地替换为被替换的任何文本。在您的示例的情况下,它将有条件地替换为 __ declspec(dllexport) __ declspec(dllimport)。这些declspec说明符另一方面告诉链接器做什么...至少有一些链接器理解说明符。



因为Microsoft实现了他们的编译器和指定它是合法的。根据C ++标准,它是不合法的。


在C ++标准的哪一部分,它说这样的类声明是合法的? / p>

没有。使用这些说明符是非标准的,不能保证在除Microsoft之外的任何其他编译器中工作。这就是为什么这种宏通常被定义为在不支持关键字的编译器中使用时扩展为空字符串(或者可能是别的,另一个实现)。


什么是__declspec(dllimport)?


这是一个非标准的关键字。您可以从他们的(Microsoft)文档中找到更多信息。



为了深入一点,关键字告诉链接器在编译共享(动态链接)库时如何导出符号。动态链接是一个完全不同于标准的概念。它是实现定义的。


我可以自己在一个程序中使用这种声明。


您打算写共享库吗?如果没有,那么你不需要知道。如果是,那么您需要阅读您要定位的每个平台的文档。



这是一个演练,可指导您完成创建动态链接库的步骤。


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.

解决方案

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.

这篇关于宏在类或函数声明的中间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆