警告 C5240:“nodiscard”:在此句法位置忽略属性

Fed*_*dor 9 c++ warnings visual-studio-2019

最近发布了 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
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*sMM 8

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

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

function-definition:
   attribute-specifier-seq_opt decl-specifier-seq_opt declarator virt-specifier-seq_opt function-body
Run Code Online (Sandbox Code Playgroud)

究其原因,这是重要的,是它指定了可选decl-specifier-seqattribute-specifier-seq(其中包括[[nodiscard]])。

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

decl-specifier-seq:
   decl-specifier attribute-specifier-seq_opt
   decl-specifier decl-specifier-seq
Run Code Online (Sandbox Code Playgroud)

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

笔记:

decl-specifier-seq 中可选的 attribute-specifier-seq 属于由前面的 decl-specifiers 确定的类型

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