C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Named Return Value Optimisation [[nrvo]]

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 8 Feb 2026 13:34:24 -0500
On Sun, Feb 8, 2026 at 7:06 AM Jens Maurer via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On 2/8/26 01:55, Frederick Virchanza Gotham via Std-Proposals wrote:
> > To achieve NRVO in C++, I think we need a happy medium between three
> things:
> > (1) Good enough functionality and convenience for programmers
>
> Sure.
>
> > (2) Not too much hassle for compiler writers
> > (3) Not too much complication for standards writers
>
> Not among the primary goals of a proposal.
>

No, but commendable secondary goals. We see way too many proposals that do
*not* consider implementability or teachability concerns, and many of them
are adopted (either permanently or temporarily).


> I think the happy medium is to mark the return slot as follows:
> >
> > mutex Func(void)
> > {
> > [[nrvo]] mutex m;
> > m.lock();
> > return m;
> > }
>
> [... rules omitted ...]
>
> How does this use of an attribute fit the idea that attributes
> have optional semantics, given that the program will be ill-formed
> without the attribute present?
>

It doesn't. Nobody *likes* the "ignorable attribute rule." See for example
https://brevzin.github.io/c++/2025/03/25/attributes/
Now, sure, "ignorable attributes" is the law of the land, on paper, for
now; but I don't think it's completely unreasonable for a std-proposals
thread to imagine the future world where the law of the land has changed,
not just for existing standard attributes like [[no_unique_address]] which
are not ignorable, or existing vendor-specific attributes like
[[gnu::section("foo")]], but for all attributes equally.

Some proposals, such as P1144 [[trivially_relocatable]], have attempted to
navigate the current rule by indicating that implementations are *permitted*
to ignore the attribute, but are *recommended* to leave
`__has_cpp_attribute(x)` false unless attribute `x` actually has the
Standard-mandated effect. This allows user-hostile-yet-conforming
implementations to ignore the attribute, while still allowing programmers
to test for support (and complain to their compiler vendors if the
attribute is not supported).


Here's the compiler patch:
> https://github.com/healytpk/gcc-thomas-healy/commit/tag_nrvo
> https://godbolt.org/z/5oe34M731


This patch actually seems quite nice. It does the thing I've always wanted
but never gotten around to doing, which is actually permitting the return
of non-movable/non-copyable types as long as the returns (or in your case,
the variables) are correctly annotated with [[nrvo]].

You're missing tests for what happens with templates like this:
    template<class T> void f() { [[gnu::nrvo]] T t; return t; }
    template void f<std::mutex>(); // certainly OK
    template void f<int>(); // this should be OK, even though `int` is not
NRVO-able, right? Because otherwise templates become kind of unusable?
At the moment, as I write this, your compiler crashes
<https://godbolt.org/z/r1o9Ga4h9> on this example.

In fact you're missing *any* tests. "Hello world" examples
<https://github.com/healytpk/gcc-thomas-healy/commit/tag_nrvo#diff-1c58b5165bb71f8d68e30f51f261d4b483d867d6b910054597531f832ffa806d>
are not tests. Your patch should touch GCC's test suite.
You should include at least one test for a situation where the programmer
has marked a variable with [[gnu::nrvo]] and returned it correctly, but
where GCC's analysis fails to do the NRVO. I see that bug #53637
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53637> gives an example
<https://godbolt.org/z/nPTdGccqK> of such a situation; but adding your
[[gnu::nrvo]] attribute to the return variable actually fixes
<https://godbolt.org/z/6YK84M8GG> that pessimization! Do you know why that
is? are there other, less trivial, cases where adding the attribute doesn't
fix the issue? and so on. (OTOH, the "fixed" code now emits a bogus
-Wunused-but-set-variable warning, which seems very wrong.)

–Arthur

Received on 2026-02-08 18:34:42