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


#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();
}

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

与尝试

  • GCC: 8.5
  • 叮当声:15.0.0
  • 编译选项:- 3 -std=c++17
  • Godbolt链接:https://godbolt.org/z/qa7TfcK9f

GCC:

<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

叮当声:

<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

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

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

您可以在这里https://eel.is/c++draft/class.mem#general看到属性只能首先出现在成员声明中。因此,

static [[nodiscard]] std::unique_ptr<A> create();

是错误的。应该是

[[nodiscard]] static std::unique_ptr<A> create();

你的代码有一个错别字。

新版本的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

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

最新更新