Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the copy-constructor called when returning LOCAL variable

Tags:

c++

I can't figure out why the copy-constructor is not called when I try to return a local variable defined within a function. See the following simplified example:

#include <iostream>
using namespace std;

class X {
public:
    X() { cout << "Default Constructor" << endl; }
    X(const X&) { cout << "Copy Constructor" << endl; }
};

X f(X x) { return x; }

X g() { 
    X y;
    return y;
}

int main() {
    cout << "First create an object" << endl;
    X a;
    cout << "Call f()" << endl;
    f(a);
    cout << "Call g()" << endl;
    g();
}

The output of the complied program is as follows

First create an object
Default Constructor
Call f()
Copy Constructor
Copy Constructor
Call g()
Default Constructor

I understand what's going on when calling f(), but have no idea why return y inside the call of g() does not trigger the copy-constructor.

like image 857
zeno tsang Avatar asked Dec 30 '13 10:12

zeno tsang


People also ask

Why is my copy constructor not being called?

The reason the copy constructor is not called is because the copy constructor itself is a function with one parameter. You didn't call such function,so it didn't execute.

Does return call copy constructor?

The copy constructor is invoked when a temporary object is created as the result of a function returning an object.

Why copy constructor does not take reference value?

When we create our own copy constructor, we pass an object by reference and we generally pass it as a const reference. One reason for passing const reference is, we should use const in C++ wherever possible so that objects are not accidentally modified.

Why there is no copy constructor in Java?

In Java it simply copies the reference. The object's state is not copied so implicitly calling the copy constructor makes no sense. And that's all there is to it really.


1 Answers

The compiler optimizes away the return copy. This is known as NRVO (Named Return Value Optimization).

in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value

The compiler is allowed to do this, even if the copy constructor has side effects.

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects.

That is, if you give your copy/move constructors side effects, your program has multiple valid execution paths, depending on whether your compiler wants to optimize or not.

like image 77
Joseph Mansfield Avatar answered Oct 26 '22 04:10

Joseph Mansfield