When a reference is initialized with another reference that's extending the lifetime of a temporary, this new reference doesn't extend anything.
But what happens when mandatory RVO prevents the reference from being copied?
Consider this example: run on gcc.godbolt.org
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
A(const A &) = delete;
A &operator=(const A &) = delete;
~A() {std::cout << "~A()\n";}
};
struct B
{
const A &a;
};
struct C
{
B b;
};
int main()
{
[[maybe_unused]] C c{ B{ A{} } };
std::cout << "---\n";
}
Under GCC this prints
A()
---
~A()
but under Clang the result is
A()
~A()
---
Which compiler is correct?
On the first glance, GCC did the right thing. But in this example:
C foo()
{
return { B{ A{} } };
}
int main()
{
[[maybe_unused]] C c = foo();
std::cout << "---\n";
}
the lifetime of A surely can't be extended beyond the function (and both compilers agree on this).
Since this snippet supposedly has the same RVO as the first one, shouldn't the behavior be the same? Thus Clang's behavior seems more consistent.