4
#include <iostream>
using namespace std;
class myclass {
public:
     myclass();
     myclass(const myclass &o);
     myclass f();
};
myclass:: myclass(){
    cout<<"Constructing normally"<<endl;
};
myclass:: myclass(const myclass &o){
    cout<<"Constructing copy"<<endl;
};
myclass myclass::f(){
    myclass temp;
    return temp;
};
int main(){
   myclass obj;
   obj = obj.f();
   return 0;
}

I found this example in a book which shows that the output of the program should be:

Constructing normally
Constructing normally
Constructing copy 

But when i compile it in my compiler it only shows the output written below

Constructing normally
Constructing normally

What is actually happening inside?

IAmBlake
  • 457
  • 6
  • 21
  • it means your compiler has optimised the copy away for the second line `obj = obj.f();` – EdChum Sep 23 '16 at 13:06
  • i couldn't get it :(.Can you please elaborate it? – IAmBlake Sep 23 '16 at 13:09
  • Read about return value optimization and copy elision (your book might be old). –  Sep 23 '16 at 13:09
  • http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization – Hatted Rooster Sep 23 '16 at 13:10
  • Your compiler decided that the copy was unnecessary so it just removed it as it decided it could construct normally and assign directly without involving the copy – EdChum Sep 23 '16 at 13:10
  • I've reopened: I can't find an exact dupe that explains why one of the copies *can't* be optimised out but the other *can* be. – Bathsheba Sep 23 '16 at 13:11
  • 1
    @EdChum: This is not entirely correct. The compiler *cannot* optimise out due to the constructor side effect. But it is allowed to exploit NRVO. – Bathsheba Sep 23 '16 at 13:11
  • 1
    @Bathsheba OK I originally thought this was copy ellision but your answer explains the difference here – EdChum Sep 23 '16 at 13:12

2 Answers2

11

Your constructor has a side effect - namely the cout call. So the compiler cannot optimise out the copy taken in obj = obj.f();.

But the C++ standard does allow it to optimise out the deep copy taken in

myclass myclass::f(){
    myclass temp;
    return temp;
};

despite there being a side effect. That allowable strategy is called Named Return Value Optimisation.

Sadly your book is really rather outdated, or factually incorrect from the outset! You could use it for kindling when lighting those cosy fires this coming winter.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
0
#include <iostream>
using namespace std;
class myclass {
public:
 myclass();
myclass(const myclass &o);
myclass f();
};
myclass:: myclass(){
cout<<"Constructing normally"<<endl;
};
myclass:: myclass(const myclass &o){
cout<<"Constructing copy"<<endl;
};
myclass myclass::f(){
myclass *temp;
return *temp;
};
int main(){
myclass obj;
obj = obj.f();
 return 0;
}