警告C5240:“nodiscard”:在此句法位置忽略属性
最近发布了 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], adecl-specifier-seq定义为:
decl-specifier-seq:
decl-specifier attribute-specifier-seq_opt
decl-specifier decl-specifier-seq
根据微软的文档__declspec,它被定义为decl-specifier; 因此,__declspec(dllexport)必须在[[nodiscard]]属性之后。
笔记:
decl-specifier-seq 中可选的 attribute-specifier-seq 属于由前面的 decl-specifiers 确定的类型
因此,[[nodiscard]] 之后的__declspec(dllexport)仅适用于__declspec(dllexport)