我有一个标有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 finalstruct [[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”的属性必须遵循
  'struct'关键字


那么,如何从GCC上的动态库导出[[nodiscard]]结构?

最佳答案

所有这些都适用于dllexportdllimport

这似乎是GCC解析器中的错误。

使用manages to parsestruct __attribute__((dllexport)) [[nodiscard]] MyObject ...版本。

@Artyer所述,GCC(和Clang)支持dllexport-[[gnu::dllexport]]的C ++语法。

还要注意的是,Windows上的GCC(MinGW)支持__declspec(dllexport)与Visual C ++兼容,并且实际上可以正确解析class __declspec(dllexport) [[nodiscard]] Test ...(已通过GCC 8.1.0测试)。



以上所有条件均假定您正在针对Windows进行编译,其中dllexport实际上表示某些含义。在其他平台上,编译器只会忽略它(通常会发出警告)。

在Linux上,应该使用-fvisibility=hidden隐藏除属性visibility("default")选择的符号以外的所有符号。没有“导入”替代方法-在构建和使用库时均使用"default"。在Linux上导出类时,不需要的任何内容都可以用visibility("hidden")标记以覆盖该类的属性。

GCC和Clang支持visibility的两种语法:__attribute__((visibility("default")))[[gnu::visibility("default")]]

可以在HERE中找到有关GCC可见性的更多信息。

我不确定从共享库中导出符号在MacOS上如何工作(也许与Linux上的相同?)。

关于c++ - gcc-如何在结构定义中组合__attribute __((dllexport))和[[nodiscard]]?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57993818/

10-11 22:50