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.

2 answers

  • answered 2018-03-13 20:26 Brian

    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.

  • answered 2018-03-13 20:26 Stephan Lechner

    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.