[[nodiscard]] GCC 和 Clang 的编译结果不同

kin*_*hah 3 c++ gcc clang c++17 nodiscard

#include <iostream>
#include <memory>

class A
{
public:
    static [[nodiscard]] std::unique_ptr<A> create();
    virtual int get_version() = 0;
    virtual ~A() = default;
};

class B : public A
{
public:
    [[nodiscard]] int get_version() override
    {
        return 20;
    }
};

std::unique_ptr<A>
A::create()
{
    return std::make_unique<B>();
}

int main()
{
    auto a = A::create();
    [[maybe_unused]] int v  = a->get_version();
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用[[nodiscard]]不允许忽略 的返回值A::create()。但是,我在 GCC 和 Clang 中得到不同的编译输出。

尝试过

  • 海湾合作委员会:8.5
  • 铿锵:15.0.0
  • 编译选项:-O3 -std=c++17
  • Godbolt 链接: https: //godbolt.org/z/qa7TfcK9f

海湾合作委员会:

<source>:7:12: warning: attribute ignored [-Wattributes]
     static [[nodiscard]] std::unique_ptr<A> create();
            ^
<source>:7:12: note: an attribute that appertains to a type-specifier is ignored
ASM generation compiler returned: 0
<source>:7:12: warning: attribute ignored [-Wattributes]
     static [[nodiscard]] std::unique_ptr<A> create();
            ^
<source>:7:12: note: an attribute that appertains to a type-specifier is ignored
Execution build compiler returned: 0
Program returned: 0
Run Code Online (Sandbox Code Playgroud)

铛:

<source>:7:14: error: 'nodiscard' attribute cannot be applied to types
    static [[nodiscard]] std::unique_ptr<A> create();
             ^
1 error generated.
ASM generation compiler returned: 1
<source>:7:14: error: 'nodiscard' attribute cannot be applied to types
    static [[nodiscard]] std::unique_ptr<A> create();
             ^
1 error generated.
Execution build compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

难道我做错了什么?为什么这些编译器有不同的行为?

此代码与 MSVC v19.33 正常配合,没有任何错误或警告: https: //godbolt.org/z/dWsv4jTo5

for*_*818 5

您可以在此处看到https://eel.is/c++draft/class.mem#general该属性只能出现在成员声明的开头。因此这个

static [[nodiscard]] std::unique_ptr<A> create();
Run Code Online (Sandbox Code Playgroud)

是错的。并且应该是

[[nodiscard]] static std::unique_ptr<A> create();
Run Code Online (Sandbox Code Playgroud)

您的代码有一个拼写错误。

新版本的 gcc会报告更清晰的错误

source>:7:12: error: standard attributes in middle of decl-specifiers
    7 |     static [[nodiscard]] std::unique_ptr<A> create();
      |            ^
<source>:7:12: note: standard attributes must precede the decl-specifiers to apply to the declaration, or follow them to apply to the type
<source>:7:12: warning: attribute ignored [-Wattributes]
<source>:7:12: note: an attribute that appertains to a type-specifier is ignored
Run Code Online (Sandbox Code Playgroud)

实际上我不知道是否必须报告错误或者警告也可以。我认为这并不重要,因为无论如何你都需要修复它,除非你忽略警告,否则你不会错过它。MSCV 不诊断问题并不好。但是,您还应该记住,[[nodiscard]]类似的属性只会鼓励编译器发出警告。不保证在丢弃时会收到警告。