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).