0

Since C++17 RVO is mandatory, but only for prvalues:

struct S {};

S foo()
{
    return S{};  // RVO mandatory
}

S foo()
{
    S s;
    return s;    // RVO not mandatory
}

I understand that RVO cannot happen for lvalues if there are multiple return paths, like:

S foo(bool condition)
{
    S a, b;
    if (condition)
        return a;
    else
        return b;
}

But if b was a reference, this should also be no problem since references cannot be reassigned:

S foo(bool condition)
{
    S a, &b = a;  // not sure if this is UB, but assume b is initialized after a
    if (condition)
        return a;
    else
        return b;
}

If b was a pointer it would be a problem since they can be reassigned.

Is there any other reason than "because the standard says so" that RVO cannot be mandatory for xvalues or lvalues? Every compiler should be able to see through those scenarios quite easily (except the counter examples of course).

Timo
  • 9,269
  • 2
  • 28
  • 58
  • 1
    Short answer: RVO did not become mandatory; the concept of a "prvalue" was *redefined* in such a way that prvalues are not necessarily objects. `return S{};` thus simply does not provoke a copy (for a function whose return type is `S`). – Nicol Bolas Jan 23 '20 at 21:51
  • @NicolBolas very interesting, is this also when the terms _materialized-_ and _unmaterialized values_ were introduced to the standard or did they exist before? – Timo Jan 23 '20 at 21:59
  • 1
    @Timo: The standard doesn’t use exactly those terms, but this is when [“temporary materialization conversion”](http://eel.is/c++draft/conv.rval) was introduced, yes. – Davis Herring Jan 24 '20 at 13:57

0 Answers0