15
votes

There is a subtle difference between the language used at cppreference.com and by the C++11 Standard regarding when the life of a temporary object is extended (emphasis mine).

From cppreference.com:

Whenever a reference is bound to a temporary or to a base subobject of a temporary, the lifetime of the temporary is extended to match the lifetime of the reference,

From The C++11 Standard:

The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

According to the standard, a subject can be a member subject, a base class subject, or an array element.

If we go strictly by the verbiage of the standard in the following sample code

struct Foo 
{
   Foo() : a(10), b(20) {}
   ~Foo() { std::cout << "In Foo::~Foo()\n"; }
   int a;
   int b;
};

Foo getFoo()
{
   return Foo();
}

void testFoo1()
{
   int const& r = getFoo().a;
   std::cout << "In testFoo1()\n";
   (void)r; // Shut up the compiler
}

the life time of the object returned by getFoo() should extend for the lifetime of the reference. However, a simple test seems to indicate that it does not.

Is the verbiage used by the standard a defect?
Is the compiler non-conformant?
Is the verbiage used by cppreference.com a defect?

Update

The language used at cppreference.com has been updated to (emphasis mine):

Whenever a reference is bound to a temporary or to a subobject thereof, the lifetime of the temporary is extended to match the lifetime of the reference, with the following exceptions:

1
A compiler doesn't do what the standard says. Must be a bug in the standard! Can't possibly be a bug in the compiler!T.C.
Snark aside, see gcc.gnu.org/bugzilla/show_bug.cgi?id=54293. This is fixed in GCC 7. cppreference and the standard are correct as written.T.C.
@T.C., The verbiage use by cppreference.com implies, whether on purpose or not, the life of a temporary object is not extended by getting a reference to a member subobject.R Sahu
Well, it didn't say it's not extended...fixed.T.C.
Work as expected with gcc/clang here.Jarod42

1 Answers

1
votes

Is the verbiage used by the standard a defect?

No.

Is the compiler non-conformant?

Yes. As was pointed out in a comment, it has been fixed in a newer version of g++, g++ 7. Related link: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54293.

Is the verbiage used by cppreference.com a defect?

Yes. The contents of the page at cppreference.com has been updated.