Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which standard wording tells us that ref-to-const temporary lifetime extension only "works once"?

Tags:

c++

I was shown the following example in chat:

#include <iostream>
struct foo { ~foo() { std::cout << "destroying!\n"; } };
const foo& func(const foo& a, const foo&) { return a; }

int main()
{
  foo x;
  const foo& y = func(foo(), x);
  std::cout << "main\n";
}

Output:

destroying!
main
destroying!

It appears to demonstrate that the lifetime of the foo temporary is not extended to entirety of main, even though it gets bound to a ref-to-const in that scope.

Presumably, then, the lifetime extension only "works once"; that is, it is applied when func's arguments are initialised, but isn't passed on through consecutive bindings.

Is my interpretation correct? If so (and if any individual paragraph is directly applicable) what's the standard wording that defines this behaviour?

like image 638
Lightness Races in Orbit Avatar asked Feb 06 '13 17:02

Lightness Races in Orbit


3 Answers

You're almost right. This behaviour actually comes from the function call specifically, not because of any sort of "only works once" rule.

Here's the wording for the whole lifetime extension "feature", with the pertinent rule emphasised in bold:

[C++11: 12.2/5]: [..] 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:

  • [..]
  • A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
  • [..]
like image 99
Lightness Races in Orbit Avatar answered Sep 28 '22 11:09

Lightness Races in Orbit


This is subject of two issue reports, http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1299 and http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1568 .

The former issue report, of which I am the reporter, was intended to cover all these cases where a reference is bound to a temporary object, but is not intended to be lifetime-extending. The description in the body of the issue only mentions prvalues being confused with temporary expressions (that actually decide whether lifetime of what they evaluate to is lengthened or not). But lvalue and xvalues are likewise confused with these in the Standard. An example where that happens in the context of static_cast is issue number #1568 (in which the use of "temporary variable" further confuses the matter).

Actually, this:

A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.

Contradicts the other rules in the same paragraph. Because the temporary is bound to both a reference parameter in a function call and to a local automatic reference variable.

like image 36
Johannes Schaub - litb Avatar answered Sep 28 '22 10:09

Johannes Schaub - litb


The rule which applies here is common sense. The standard is poorly worded, and does in fact guarantee this. But there's no practical way to implement it.

like image 37
James Kanze Avatar answered Sep 28 '22 11:09

James Kanze