*As a remainder, an lvalue is an expression that can be on the left
side of an operation. In the C times it could be characterized as
"having an address" or "having a name". With C++, it is a bit more
complicated. For example f() can be an lvalue if f returns a reference
to something. On the other hand, an rvalue is an expression that is not
an lvalue. For example "a+b" is not an lvalue. You cannot assign a value
to "a+b". Well, except if you override operator+ to return a reference,
again.*

Move semantics and rvalue references are new concepts in C++11. I am going to cover them at the same time because they are linked. Basically, rvalue references are non-const references to rvalues (typically: objects that are going out of scope). On the other hand, the "move constructor" concept allows constructing an object by "stealing" the content of another object that is going to be destroyed.

## Why introduce a new concept ?

If you construct an object from a temporary object, which by essence will be destructed soon afterwards, the basic way is to copy the content of the temporary object, then let it be destroyed. Imagine the overhead when the object is a huge matrix, or contains resources such as file handles or sockets in its members. In this case, it would seem much more intuitive to "steal" its resources. The newly allocated object's constructor would then really cheap, and the temporary object destructor should destroy nothing.

This is what those new concepts allow. This "stealing" constructor is called a move constructor, and it takes as parameter an "rvalue reference", which is a non const reference to a temporary object. This parameter really needs to be non const, since we are going to get its resources and update it from deleting them.

Of course you might think that you never have to use all of this, simply because you only transfer objects by reference when that have a big memory footprint or carry resources such as file handles. You might also always work on objects that do shallow copies, i.e. really contains just reference counted pointers to these big objects. Well in those cases, move constructors can be useful to simplify the existing code, and can improve the performance of existing code by introducing the new semantics of the move constructor.

## Examples

Let's assume you have a class called Matrix that has some important memory impact. You can do some operations on matrixes, which return new Matrix objects. At the same time, you would want to minimize deep copy whenever possible, and work on existing matrixes when you can. In the following sample code, a matrix contains just an array of 10 integers. To be able to see easily the impact of move semantics, outputs are done when a "heavy" operation is done (allocating/freeing memory, copying data, ...). The move semantics have been put at the end of the class, and can be enabled or disabled at will.

*Warning: I'm using an array of int values just as a sample of
allocating and swapping resources in the move constructor. Things would
obviously not be implemented this way in the real world.*
So let's say you have this stripped-down Matrix class:

```
class Matrix
{
public:
Matrix()
{
std::cout << " Constructing a new matrix. Allocating 10 ints" << std::endl;
customData = new int[10];
}
~Matrix()
{
if (customData != nullptr)
{
std::cout << " Destructing a matrix. Freeing 10 ints." << std::endl;
delete[] customData;
}
}
Matrix(Matrix const& m)
{
std::cout << " Copy constructing a matrix. Allocating 10 ints and copy all data." << std::endl;
customData = new int[10];
std::copy(m.customData, m.customData + 10, customData);
}
Matrix& operator= (Matrix const& m)
{
if (this != &m)
{
std::cout << " Assigning a matrix. Copy all data." << std::endl;
std::copy(m.customData, m.customData + 10, customData);
}
return *this;
}
Matrix& operator+=(Matrix const& m)
{
std::cout << " Adding a matrix to another" << std::endl;
return *this;
}
Matrix& operator*=(Matrix const& m)
{
std::cout << " Multiplying a matrix to another" << std::endl;
return *this;
}
Matrix operator+(Matrix const& m) const
{
Matrix result(*this);
result += m;
return result;
}
Matrix operator*(Matrix const& m) const
{
std::cout << " Multiplying a matrix to another" << std::endl;
Matrix result(*this);
result *= m;
return result;
}
private:
int *customData;
};
```

And you want to do a computation like: m1 + m4 * (m3 + (m1 * m2))

```
int main()
{
Matrix m1, m2, m3, m4;
{
Matrix operation(m1);
operation *= m2;
operation += m3;
operation *= m4;
operation += m1;
}
return 0;
}
```

Here is the corresponding output:

Initialization Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Copy constructing a matrix. Allocating 10 ints and copy all data. Multiplying a matrix to another Adding a matrix to another Multiplying a matrix to another Adding a matrix to another Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints.

We don't waste any memory on this example because all the computations are done "in place" in the matrix called "operation". Problem is: this is not really readable. Imagine we want to build more complex operations, things will eventually get really hard to follow. So let's turn to operator overloading in C++, our example becomes:

```
int main()
{
Matrix m1, m2, m3, m4;
{
Matrix operation = m1 + m4 * (m3 + (m1 * m2));
}
return 0;
}
```

This is much more concise and readable than the former. But let's take a look at the output:

Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Multiplying a matrix to another Copy constructing a matrix. Allocating 10 ints and copy all data. Multiplying a matrix to another Copy constructing a matrix. Allocating 10 ints and copy all data. Adding a matrix to another Multiplying a matrix to another Copy constructing a matrix. Allocating 10 ints and copy all data. Multiplying a matrix to another Copy constructing a matrix. Allocating 10 ints and copy all data. Adding a matrix to another Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints.

Each operation is allocating a new matrix ! We are now using twice as much memory as the in place version. What if we want both readability AND performance ? That's where move semantics comes to help. Suppose you add these members to your existing Matrix class. That's right, you don't have to modify existing code to take advantage of move semantics.

```
Matrix(Matrix && a)
{
customData = a.customData;
a.customData = nullptr;
}
Matrix operator*(Matrix && m) const
{
std::cout << " Multiplying a matrix with a temporary matrix" << std::endl;
Matrix result(std::forward< Matrix>(m));
result *= *this;
return result;
}
Matrix operator+(Matrix && m) const
{
std::cout << " Adding a matrix with a temporary matrix" << std::endl;
Matrix result(std::forward< Matrix>(m));
result += *this;
return result;
}
Matrix& operator=(Matrix && m)
{
if (this != &m)
{
std::cout << " Assigning a matrix from a temporary. Free our current data." << std::endl;
delete[] customData;
customData = m.customData;
m.customData = nullptr;
}
return *this;
}
```

We don't need to change the contents of the "main" function. Here's the corresponding output:

Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Constructing a new matrix. Allocating 10 ints Multiplying a matrix to another Copy constructing a matrix. Allocating 10 ints and copy all data. Multiplying a matrix to another Adding a matrix with a temporary matrix Adding a matrix to another Multiplying a matrix with a temporary matrix Multiplying a matrix to another Adding a matrix with a temporary matrix Adding a matrix to another Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints. Destructing a matrix. Freeing 10 ints.

Basically, we're back to the memory footprint of the first, unreadable computation style. You might notice that the code for the + and * operators are similar for const references and rvalues references. On a real life example, you would want to use templates for operators, like this:

```
template < typename t="t" >
Matrix operator*(T && m) const
{
Matrix result(std::forward< t >(m));
result *= *this;
return result;
}
```

## Pitfalls

As the C++ gurus say "C++ will never prevent a developer from shooting himself in the foot". There are some pitfalls that you might want to avoid when working with rvalue references:

### Calling the wrong override

```
void g(A const& a)
{
// Do something with a
}
void g(A && a)
{
// Do something else with a
}
void f(A && a)
{
g(a);
}
```

This is not obvious at all when you're not yet used to rvalue
references, but the override that gets called by f is g(const&). This is
the case because, even if a's type is "rvalue reference of an A", it is
still an lvalue **in the context of the function**: we can know its
address, and more importantly we still have access to it after g(a). If
we were to call g(a+b) for example, the rvalue reference overload would
be called because a+b is not a variable name, and would be out of scope
after the right parenthesis of g(a+b).

In other words, we must never forget what a rvalue is: an object that is going out of scope, an object which we can never refer to anymore. This is not the case inside f, where a is a parameter, and not a temporary value (even if it really references a temporary value).

### Difficulty to see improvements with small samples

gcc already optimizes much with Return Value Optimization and copy elision. It may be difficult to test rvalue references with small tests because of this. In real code, though, the benefits are real if you remember to always use rvalue references when it is possible and meaningful to do so.

## Going further

See this article that goes into the deepest details of the move and rvalue references semantics here.

## Comments

comments powered by Disqus