Search code examples
c++attributeslanguage-lawyerc++17friend-function

`friend` member functions and attributes - gcc vs clang


The following code snippet:

struct a
{
    [[nodiscard]] friend int b();
};

Produces this error when compiling on clang++ (trunk 342102) with -std=c++17:

<source>:3:5: error: an attribute list cannot appear here
    [[nodiscard]] friend int b();
    ^~~~~~~~~~~~~

Removing friend or adding a body to b prevents the error.

g++ (trunk) compiles the code just fine.

Live example on godbolt: https://gcc.godbolt.org/z/ttTDuZ


  • Is this a clang++ bug? Or is there some rule in the Standard that makes this code ill-formed?

  • If clang++ is correct, what's the proper way of marking a friend member function as [[nodiscard]]?


Solution

  • Per [dcl.attr.grammar]/5

    Each attribute-specifier-seq is said to appertain to some entity or statement, identified by the syntactic context where it appears ([stmt.stmt], [dcl.dcl], [dcl.decl]). If an attribute-specifier-seq that appertains to some entity or statement contains an attribute or alignment-specifier that is not allowed to apply to that entity or statement, the program is ill-formed. If an attribute-specifier-seq appertains to a friend declaration, that declaration shall be a definition. No attribute-specifier-seq shall appertain to an explicit instantiation.

    emphasis mine

    So, clang is right here. If you have an attribute, the function must have a definition if it is a friend function.