警告 C5240:'nodiscard':在此语法位置忽略属性

warning C5240: 'nodiscard': attribute is ignored in this syntactic position

最近 Visual Studio 2019 版本 16.9.5 已经发布。它显然引入了新警告:

[[nodiscard]] __declspec(dllexport) bool foo(); //ok
__declspec(dllexport) [[nodiscard]] bool bar(); // warning C5240: 'nodiscard': attribute is ignored in this syntactic position

其实我以为nodiscard和dllexport都是可以任意顺序出现的属性,其实不是?

我今天也收到了这个警告,所以决定调查一下。这需要稍微了解一下标准,并将不同的部分放在一起。

根据[dcl.fct.def.general],函数定义为:

function-definition:
   attribute-specifier-seq_opt decl-specifier-seq_opt declarator virt-specifier-seq_opt function-body

之所以重要,是因为它指定可选的 decl-specifier-seq 在 之后 attribute-specifier-seq(包括 [[nodiscard]]) .

现在,根据[dcl.spec.general],一个decl-specifier-seq定义为:

decl-specifier-seq:
   decl-specifier attribute-specifier-seq_opt
   decl-specifier decl-specifier-seq

根据微软__declspec的文档,定义为decl-specifier;因此,__declspec(dllexport) 必须在 [[nodiscard]] 属性之后。

注:

The optional attribute-specifier-seq in a decl-specifier-seq appertains to the type determined by the preceding decl-specifiers

因此,[[nodiscard]] after __declspec(dllexport) 仅适用于 __declspec(dllexport)