Reputation: 93264
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]]
?
Upvotes: 12
Views: 1085
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
Reputation: 180490
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