mardi 3 mai 2016

C++11 move semantics when return a local object

I saw some similar questions but could not find a clear explanation for my problem. Here is the code (that can be found here: http://ift.tt/1Zb7qx5):

#include <iostream>

class A {
  public:
  explicit A(int a)         {std::cout << "Main constructor" << std::endl;}
  A(const A& a)             {std::cout << "Copy constructor" << std::endl;}
  A& operator =(const A& a) {std::cout << "Copy assignment" << std::endl; return *this;}
  A(A&& a)                  {std::cout << "Move constructor" << std::endl;}
  A& operator =(A&& a)      {std::cout << "Move assignemnt" << std::endl; return *this;}
};

A getA(bool b)        {std::cout << "In getA" << std::endl; A a(0); return b ? a : A(1);}
A getA_Move(bool b)   {std::cout << "In getA_Move" << std::endl; A a(0); return std::move(b ? a : A(1));}

int main(void) {
    std::cout << "\nA a0(getA(true))" << std::endl;
    A a0(getA(true));
    std::cout << "\nA a1(getA(false))" << std::endl;
    A a1(getA(false));    
    std::cout << "\nA a2(getA(true))" << std::endl;
    A a2(getA_Move(true));
    std::cout << "\nA a3(getA(false))" << std::endl;
    A a3(getA_Move(false));    
}

As far as I understood: The return of a function is an rvalue (because as opposite to an lvalue it has no name and thus cannot be re used). Thus when creating an object which is taking the return value of a function as a parameter this parameter should be moved if it is moveable. However this is not what I can observe:

Start


A a0(getA(true))
Main constructor
In getA
Copy constructor  <- Why is not this a move ?

A a1(getA(false))
Main constructor
In getA
Main constructor

A a2(getA(true))
Main constructor
In getA_Move
Copy constructor <- I would have expected a move here as well
Move constructor

A a3(getA(false))
Main constructor
In getA_Move
Main constructor
Move constructor

0

Finish

If I deactivate RVO (with -fno-elide-constructors see http://ift.tt/1rTnMAv), then I get:

Start


A a0(getA(true))
Main constructor
In getA
Copy constructor  <- this is certainly the creation of the return value.
Move constructor  <- OK move the return value
Move constructor

A a1(getA(false))
Main constructor
In getA
Main constructor
Move constructor
Move constructor

A a2(getA(true))
Main constructor
In getA_Move
Copy constructor
Move constructor
Move constructor

A a3(getA(false))
Main constructor
In getA_Move
Main constructor
Move constructor
Move constructor

0

Finish

Aucun commentaire:

Enregistrer un commentaire