Vittorio Romeo
Vittorio Romeo

Reputation: 93264

`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


Upvotes: 12

Views: 1085

Answers (2)

Baptistou
Baptistou

Reputation: 2101

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99032

The bug is fixed in GCC 12, you now have the following warning.

test.cpp:3:30: warning: attribute ignored [-Wattributes]
    3 |     [[nodiscard]] friend int b();
      |                              ^
test.cpp:3:30: note: an attribute that appertains to a friend declaration that is not a definition is ignored

The proper way of marking a friend member function as [[nodiscard]] is to put the attribute on its definition.

struct a
{
    friend int b();
};

[[nodiscard]] int b(){ return 42; }

Upvotes: 0

NathanOliver
NathanOliver

Reputation: 180490

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.

Upvotes: 15

Related Questions