Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is reference binding to a temporary of a temporary undefined behavior?

In the following the snippet, is the lifetime of the sphere extended in such a way that the value of r is not undefined?

 struct Sphere {
   auto& radius() const { return _radius;}
   float _radius{};
 };
 struct Capsule {
   auto sphere() const { return Sphere{12.0}; }
 };
 auto func() {
   auto capsule = Capsule{};
   const auto& r = capsule.sphere().radius();
   std::cout << r;
 }

I know that const-references extend the life time of a temporary, but I'm not sure what happens if a member of a temporary is bound to.

Note: I'm very suspicious that the equivalent of this snippet is causing a bug for me, but neither Clang nor Visual Studio issues a warning.

like image 852
Viktor Sehr Avatar asked Mar 13 '18 20:03

Viktor Sehr


2 Answers

In order for lifetime extension to occur, the reference must bind to a prvalue (which is then materialized into a temporary object so that the reference has something to bind to). However, capsule.sphere().radius() is not a prvalue; it is an lvalue that refers to Sphere::_radius. Therefore lifetime extension does not occur, and the Sphere object together with its _radius member will be destroyed at the end of the full-expression.

like image 101
Brian Bi Avatar answered Sep 21 '22 13:09

Brian Bi


The lifetime of the temporary Sphere-object is extended only until the completion of the full expression containing the call. The full expression is const auto& r = capsule.sphere().radius(); and not longer, such that r lives longer than the full expression and it's temporary. So I'd clearly vote for undefined behaviour.

like image 31
Stephan Lechner Avatar answered Sep 19 '22 13:09

Stephan Lechner