【发布时间】:2019-09-18 13:22:54
【问题描述】:
我有一个标有 C++17 的 [[nodiscard]] 属性的结构。它是这样定义的:
struct [[nodiscard]] MyObject final
{
explicit MyObject(int id);
~MyObject();
MyObject(const MyObject&) = delete;
MyObject& operator=(const MyObject&) = delete;
int id;
};
现在我想从我的动态库中导出它。
在 MSVC 上,语法 struct __declspec(dllexport) [[nodiscard]] MyObject final 按预期工作。
但是 GCC 无法同时编译 struct __attribute__((dllexport)) [[nodiscard]] MyObject final 和 struct [[nodiscard]] __attribute__((dllexport)) MyObject final:编译器无法处理这样的语法。
语法__attribute__((dllexport)) struct [[nodiscard]] MyObject final 编译但似乎没有做我想要的,因为它会产生以下警告:
:1:49: 警告: 'struct 声明中忽略的属性 MyObject' [-Wattributes]
1 | __attribute__((dllexport)) struct [[nodiscard]] MyObject final | ^~~~~~~~:1:49: 注意:'struct MyObject' 的属性必须遵循 “结构”关键字
那么,如何从 GCC 上的动态库中导出 [[nodiscard]] 结构?
【问题讨论】:
-
@andrey 您提供的链接向我显示了带有
__attribute__((visibility("default")))而不是__attribute__((dllexport))的代码。如果我用__attribute__((dllexport))替换它,我会收到以下警告:unknown attribute 'dllexport' ignored [-Wunknown-attributes]。 -
那是因为带有 Clang 的 Compiler Explorer 节点正在运行 Linux。
dllexport用于 DLL,它们是 Windows 共享库。 Linux(也可能是 MacOS)上共享库的等效属性是visibility("default"),在命令行上是-fvisibility=hidden。在为 Linux 构建时,编译器自然无法识别dllexport属性(它是如何编写的),但重要的是该属性被正确解析(即使它随后被忽略)。 -
@andrey 是的,我在 Linux 上测试了该代码,但我对在 Linux 上创建共享库知之甚少,所以我认为 Linux 编译器也能够以某种方式识别
dllexport.好的,所以我应该改用__attribute__((visibility("default")))。这很清楚。那么,事实上,它很可能是一个(又一个)GCC 错误。如果您将其写为答案,我会将其标记为已接受。