12

Updating the question Why this two rvalue references examples have different behavior?:

Source code:

int a = 0;
auto && b = a++;
++a;
cout << a << b << endl;

prints 20

Is it undefined behavior (UB) to use b after the a++ call? Maybe we cannot use b because it refers to a temporary?

Community
  • 1
  • 1
vladon
  • 8,158
  • 2
  • 47
  • 91
  • 2
    This document could be useful to you : http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf – dkg Feb 10 '16 at 13:01
  • 1
    Hmm, from my understanding it's not as the value of the temporary from `a++`is "moved" to `b`. Yet I think it might be UB if you would use `auto && b = ++a;` as in your example in the other question. But I may be totally wrong as I am not really familiar with move semantics. – Simon Kraemer Feb 10 '16 at 13:04
  • @dkg Is it actual for references to rvalues introduced in C++11 (`&&`)? – vladon Feb 10 '16 at 13:05
  • 2
    @SimonKraemer and OP you may want to see: http://stackoverflow.com/questions/13230480/what-does-auto-tell-us – NathanOliver Feb 10 '16 at 13:09
  • @NathanOliver Really informative. Thank you for the link. – Simon Kraemer Feb 10 '16 at 13:12

3 Answers3

13

The code is fine. b refers to a lifetime-extended object that is the result of the expression a++, which is a different object from a. (Binding a temporary object to a reference extends the lifetime of the object to that of the reference.) You can use and modify both objects.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • but in C++98 it was `binding a temporary to a CONST reference extends...` so that's quite scary, thus the need to check twice :) – v.oddou Mar 22 '19 at 06:59
  • @v.oddou: I think that's a misleading way to think about it. What matters is the "binding to a reference". Whether you *can* in fact bind to a reference is a separate, unrelated rule. In C++98 rvalues can bind to const lvalue references only; in C++11 they can also bind to any (cv-compatible) rvalue reference. – Kerrek SB Mar 22 '19 at 10:18
7

No it is not undefined behavior (UB). It's fine - you can modify the contents of the temporary here (so long as the reference is valid for the lifetime of the temporary, in this case the bind to the rvalue reference extends that lifetime of the rvalue to the lifetime of the reference).

A more general question is; is it UB to modify a temporary through the rvalue reference? No it is not UB. Move semantics, where the "moved-to" object "steals" the "moved-from" object's contents, relies on this to be well defined.

Niall
  • 30,036
  • 10
  • 99
  • 142
3

Taking a reference to a temporary extends its lifetime to the end of lifetime of that reference.

ISO/IEC 14882 § 12.2/5:

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 […]

Jan Hudec
  • 73,652
  • 13
  • 125
  • 172