C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Stop gap required for NRVO until Anton's paper is assimilated

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Thu, 11 Jul 2024 19:08:14 +0000
> Let's assume that by "variable" you mean "variable that's not a parameter, and of automatic lifetime (not static or thread_local), and has the same type (possibly cv-qualified) as the return type."

Yes, that are conditions that need to be disqualified, things that are not obviously constructable in the return slot. This is by no means necessarily easy to deduce, surely not a one sentence change to the text. But I feel that the spirit of it is correct. It’s an oversimplified sentence, I agree with that.
Things returned on the register are indeed tricky to define, but if they are returnable in a register they are also trivially copiable, or at least transferring it in and out of stack/register could not change its nature of the object making it mute where you would put it.

> What would be the difference between what you're asking for, and what P2025 proposed?

In spirit nothing. If it can RVO it will RVO, no annotations required. The hard part is figuring out the corner cases that may not be trivial to describe in the language of the current standard and in face of the Zoo of all the different categories of variables.
I think it is good in principle and just needs to work out the kinks.

> That makes some things a lot easier; e.g. you almost (not quite) get correct handling of non-automatic variables for free, since they remain "alive" even when they're not "in scope".
> However, I think your choice makes the spec a lot harder, because C++ compilers need a foolproof way to decide whether they're going to do RVO on a variable at compile time, where all that's available to them is the lexical scoping of things

I think this should be more limited to automatic variables. Stuff that the compiler is able to observe and have to decide when to emit code to destroy those variables.
I think it is my fault for oversimplifying the sentence.

> FYI, I have exactly that idea in my Clang fork:
https://godbolt.org/z/fcK1b46c1 (right-hand pane is my P1144 compiler with my annotated -Wnrvo; left-hand pane shows GCC trunk's different behavior for unannotated -Wnrvo)

great I like it. If we have independently arrived at the same solution, it might be a good indication that we might be on the right track 😊




From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Sent: Thursday, July 11, 2024 18:53
To: std-proposals_at_[hidden]
Cc: Tiago Freire <tmiguelf_at_[hidden]>
Subject: Re: [std-proposals] Stop gap required for NRVO until Anton's paper is assimilated

On Thu, Jul 11, 2024 at 12:13 PM Tiago Freire via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>> wrote:
The way I see it, any other solution that is not achieving guaranteed nrvo extensions without any additional markings (this includes functions) is a waste of time.

I intuitively agree with that statement; but I believe other participants have said that RVO without annotation is unattractive to them because it's not reliable (i.e. "faillure" is not diagnosable); they want markup, so that they can be alerted when the markup fails.
GCC trunk just recently added something (tentatively?) called "-Wnrvo" that attempts to diagnose failures of RVO without any markup. I encourage you to try it out and see if it meets your needs. In practice, I suspect it will not meet your needs.
Related bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115718

What you need is quite simple.
Any named variable X that is returned should guarantee nrvo unless a return statement exist that does not return X and X is alive.

Let's assume that by "variable" you mean "variable that's not a parameter, and of automatic lifetime (not static or thread_local), and has the same type (possibly cv-qualified) as the return type."
And let's assume that the return type is sufficiently non-trivial so that it does not trigger [class.temporary]/3<https://eel.is/c++draft/class.temporary#3>.
You'll have to decide whether catch-clause parameters count as non-parameter local variables (per P2025), or not (per the status quo).
The return statement that "exists" has to be returning from the current function (returns hidden inside lambdas don't interfere).

...None of these sound like showstoppers at all, but at least they show that the proposal isn't one sentence. It's about as complicated as P2025 — and not surprising, because P2025 is basically trying to do what you're asking for, isn't it? What would be the difference between what you're asking for, and what P2025 proposed?

The one big thing I see your sentence doing differently from P2025 is that you're talking in terms of "lifetime" rather than in terms of "scope."
That makes some things a lot easier; e.g. you almost (not quite) get correct handling of non-automatic variables for free, since they remain "alive" even when they're not "in scope".
However, I think your choice makes the spec a lot harder, because C++ compilers need a foolproof way to decide whether they're going to do RVO on a variable at compile time, where all that's available to them is the lexical scoping of things — the dynamic behavioral stuff like lifetime isn't directly available until runtime, which is too late. So you'll have to specify a standard heuristic mapping runtime lifetime onto some compile-time property (like scope) — which, again, is exactly where P2025 ended up.

[...]
If there are any markings to be added, these would be in terms of attributes that have no effect on the generated code, but mark expectations on behavior (like [[fallthrough]], or [[maybe_unused]]):
i.e. you can mark a return statement as [[rvo]] (or something), but that only serves to issue a compiler warning in case the return statement cannot actually achieve rvo, either or not a variable is rvo is not dependent on the attribute.

FYI, I have exactly that idea in my Clang fork:
https://godbolt.org/z/fcK1b46c1 (right-hand pane is my P1144 compiler with my annotated -Wnrvo; left-hand pane shows GCC trunk's different behavior for unannotated -Wnrvo)

–Arthur

Received on 2024-07-11 19:08:22