C++ Logo


Advanced search

Re: [std-proposals] [[nodiscard]] friend

From: Robert Allan Schwartz <notbob_at_[hidden]>
Date: Wed, 18 Jan 2023 18:41:00 +0000
Hi Arthur,

Today is my first day submitting things to the Standard community. I don't know anything about pull requests, etc.

I'm not seeking to complicate the grammar.
I'm not seeking to create burdens for all of those people.
I'm not seeking to make a stylistic choice.

I am seeking to not have the syntax dominate and control the semantics.

If I declare a function as:

[[nodiscard]] void foo();

or I define a function as:

[[nodiscard]] void foo()

then the attribute is part of the interface of the function.

If I grant friendship to that function, it seems to me that I should say:

class bar
friend /* the interface of the function I want to grand friendship to */;

which would be:

class bar
friend [[nodiscard]] void foo();

That's all I'm seeking to do.

I'm aware of the rules in the grammar that currently require attribute specifiers to come before decl specifiers:


decl-specifier-seq init-declarator-listopt ;

attribute-specifier-seq decl-specifier-seq init-declarator-list ;

attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ;

but perhaps this could be changed to:


decl-specifier-seq init-declarator-listopt ;

attribute-specifier-or-decl-specifier-seq init-declarator-list ;

attribute-specifier-or-decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ;


attribute-specifier-or-decl-specifier-seq attribute-specifier-or-decl-specifier





which might not impose a huge burden on compiler writers.



On Jan 18, 2023, at 12:35 PM, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> wrote:

On Wed, Jan 18, 2023 at 11:51 AM Robert Allan Schwartz via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> wrote:

Header <stop_token>:

[[nodiscard]] friend bool operator==(const stop_token& lhs, const stop_token& rhs) noexcept;

I would have thought that this should be:

friend [[nodiscard]] bool operator==(const stop_token& lhs, const stop_token& rhs) noexcept;

i.e. the attribute pertains to the function, not to the friend declaration,
but I was told that an attribute cannot appear in this position,
hence it must be as it is in <stop_token>.

Perhaps the grammar should be amended to allow an attribute in this position?

Hi Robert,
(Unlike your other thread, this one is a feature request / behavioral change, and thus would have to be proposed as a paper and discussed in committee; even if you had wording for it, it should never be submitted as a pull request. Just so we're clear on that. :))

This proposal lacks motivation. You're asking to complicate the grammar, right? This will create burdens for the committee/specifiers, for compiler vendors/implementors, for users who now have to deal with yet another little difference between C++2b and C++2c. Those are all costs. And the benefit is... what? That you now get a stylistic choice of two different places it's legal to put attributes like `[[nodiscard]]`?
Alternatively, just don't do any of that; and then the only cost is to (an ever-decreasing number of) programmers who would stylistically prefer to write `friend [[nodiscard]] bool` but are forced by the simple grammar of C++ to write `[[nodiscard]] friend bool`. That's a much smaller cost than all the costs above; and it has all the same benefits plus two — compiler enforcement of the preferred style (the alternative style is rejected by the compiler, hooray!), and its already-being-implemented-as-the-status-quo (so vendors don't need to do any work).

my $.02,

Received on 2023-01-18 18:41:05