c++visual-studio-2019warningsnodiscard

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


Recently version 16.9.5 of Visual Studio 2019 has been released. It apparently introduced new warning:

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

Actually I thought that both nodiscard and dllexport are attributes that can appear in any order, or it is not?


Solution

  • I got this warning today too, so decided to look into it. This requires looking a bit at the standard, and putting different sections together.

    According to [dcl.fct.def.general], a function is defined as:

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

    The reason this is important, is that it specifies that the optional decl-specifier-seq comes after the attribute-specifier-seq (which includes [[nodiscard]]).

    Now, according to [dcl.spec.general], a decl-specifier-seq is defined as:

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

    According to Microsoft's documentation of __declspec, it is defined as a decl-specifier; thus, the __declspec(dllexport) must come after the [[nodiscard]] attribute.

    Note:

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

    Thus, the [[nodiscard]] after the __declspec(dllexport) applies only to the __declspec(dllexport)