Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens when you assign a literal constant to an rvalue reference?

This is admittedly a nit-picky question that is mainly driven by curiosity. Suppose we have the following:

int x = 5;
int&& xref = std::move(x);
std::cout << "Before assignment x: " << x << std::endl;
std::cout << "Before assignment xref: " << xref << std::endl;
xref = 10;
std::cout << "After assignment x: " << x << std::endl;
std::cout << "After assignment xref: " << xref << std::endl;

The output as expected is:

// Before assignment x: 5
// Before assignment xref: 5
// After assignment x: 10
// After assignment xref: 10

This makes sense. std::move converts x to an xvalue and allows us to bind its memory location to xref and modify its contents accordingly. Now lets say we have the following:

int&& xref = 5;
std::cout << "Before assignment xref: " << xref << std::endl;
xref = 10;
std::cout << "After assignment xref: " << xref << std::endl;

int x = 5;
std::cout << "After assignment x: " << x << std::endl;

The output is intuitively:

// Before assignment xref: 5
// After assignment xref: 10
// After assignment x: 5

This make overall sense. We expect to be able to bind the constant literal 5 to xref because 5 is a prvalue. We also expect that xref be mutable. We further expect that the value of constant literal 5 isn't modifiable (as shown somewhat pedantically in the last two lines of the above snippet).

So my question is, what exactly is going on here? How does C++ know not to modify the value of the constant literal 5 yet maintain sufficient identity for xref to know that it's been changed to 10 by the assignment. Is a new variable being created upon assignment to xref when its bound to a constant literal? This question never came up in C++03 since only const references could be bound to rvalues.

like image 610
Klam Avatar asked Oct 12 '15 16:10

Klam


2 Answers

int&& xref = 5;

... creates a temporary, initialized with 5, whose lifetime is extended to the end of the block.

The assignment

xref = 10;

changes the value of the still living temporary.

like image 166
Cheers and hth. - Alf Avatar answered Nov 11 '22 07:11

Cheers and hth. - Alf


A temporary is constructed, initialised from the value of the literal, and it lasts as long as the reference. You can do what you like with this object.

In terms of lifetime, this is just the same as if you'd written const int& x = 5; only, there, the fact that you're working with an automatically-created temporary object is masked because the const prevents you from proving it with a mutation.

[C++14: 8.5.3/5]: [..] If T1 is a non-class type, a temporary of type “cv1 T1” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary. [..]

like image 45
Lightness Races in Orbit Avatar answered Nov 11 '22 08:11

Lightness Races in Orbit