1

I have the following simple c++ code :

class X {
    public :
    int x ;
    X(int val) : x(val) {cout<<"one arg\n" ;} 
    X(const X&xx) {cout<<"const copy constr\n" ; x = xx.x ;}
    X(X&xx) {cout<<"non const copy constr\n" ; x = xx.x ;}
    X(const X&&xx) {cout<<"const move constr\n" ; x = xx.x ;}
    X(X&&xx) {cout<<"non const move constr\n" ; x = xx.x ;}
    X operator +(X &ob) {
        X xx(x+ob.x) ; cout<<"add\n" ; return xx ;
    }
    X operator=(const X &x) {cout<<"const assign\n" ;}
    X operator=(X &x) {cout<<"non const assign\n" ;}
    X operator=(const X &&x) {cout<<"const move assign\n" ;}
    X operator=(X &&x) {cout<<"non const move assign\n" ;}
} ;

main() {
    X   x1(10), x2(x1) ;
    cout<<"$$$$$$$$$$$$$$\n" ;
    X   x3 = x1+x2 ;//does not invoke move/copy constr ---> do not know why
    cout<<"###########"<<x3.x<<endl ;
    cout<<"$$$$$$$$$$$$$$\n" ;
    vector<X>   v ;
    v.push_back(X(100)) ;//invokes move constr

}

Via which constructor is the object x3 created ?

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
user3282758
  • 1,379
  • 11
  • 29

1 Answers1

4

There are a bajillion duplicates of this question on stackoverflow, the move/copy is elided, see http://en.wikipedia.org/wiki/Copy_elision

As stated in the GCC FAQ ("My copy constructor doesn't run!") when using gcc (or clang) compile with -fno-elide-constructors to see every intermediate temporary object getting copied or moved, but there's no reason to do that because it makes your program much slower.

What you're observing is that the X inside operator+ is constructed at the stack location reserved for x3, and so there is no copy or move needed because an X with the right value has already been constructed at the right location. If you print out the address of xx and the address of x3 you will see they are the same object.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521