On Thu, Jul 11, 2024 at 12:13 PM Tiago Freire via Std-Proposals <std-proposals@lists.isocpp.org> 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.
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