brenmcnamara
brenmcnamara

Reputation: 469

Where is copy constructor getting called?

I wrote a small snippet of C++ code in a main.cpp file and am trying to understand how it's working.

First I defined a class "Value":

#include <algorithm>
#include <iostream>

using namespace std;

class Value {

  int v;

 public:

  Value(int v): v(v) {
    cout << "Ctor called" << endl;
  }

  Value(const Value &rhs): v(rhs.v) {
    cout << "Copy Ctor called. V = " << v << endl;
  }

  Value& operator =(const Value &rhs) {
    cout << "Assignment called" << endl;
    if (this != &rhs) {
      auto tmp = Value(rhs);
      swap(v, tmp.v);
    }
    return *this;
  }

  int rawValue() const {
    return v;
  }

};

Then I executed main:

Value doubleValue(const Value &v) {
  auto newValue = Value(v.rawValue() * 2);
  return newValue;
}

int main() {
  cout << "Creating v = 10" << endl;
  auto v = Value(10);

  cout << "Creating v = 20" << endl;
  auto v2 = doubleValue(v);

  return 0;
}

I'm using g++ as my compiler and when I run the following code:

g++ --std=c++11 -fno-elide-constructors -c main.cpp
g++ main.o -o main.exe
./main.exe

Which prints the following:

Creating v = 10
Ctor called
Creating v = 20
Ctor called

I compile the code again, but without the copy constructors getting optimized out:

g++ --std=c++11 -fno-elide-constructors -c main.cpp
g++ main.o -o main.exe
./main.exe

And now, it print the following:

Creating v = 10
Ctor called
Copy Ctor called. V = 10
Creating v = 20
Ctor called
Copy Ctor called. V = 20
Copy Ctor called. V = 20
Copy Ctor called. V = 20

Not sure why it's calling the copy constructor so many times. I'm a C++ noob and would like to understand the flow much better. I'm curious to know how this code is running and why the copy constructor is getting called so often.

Upvotes: 1

Views: 54

Answers (2)

Alexey Malistov
Alexey Malistov

Reputation: 26975

Read about Return value optimization (RVO). If RVO is off then your copy constructor is getting called very often. If RVO is on then, for example, the code auto v = Value(10); omits copy ctor calls.

Upvotes: 1

M.M
M.M

Reputation: 141574

Here are the copies:

  • auto v = Value(10); initializes v using copy-constructor from Value(10).
  • auto newValue = Value(v.rawValue() * 2); initializes newValue using copy-constructor from Value(v.rawValue()*2).
  • return newValue; initializes the return value using copy-constructor from newValue.
  • auto v2 = doubleValue(v); initializes v2 using copy-constructor from the return value.

All of these are copy-elision contexts.

Upvotes: 3

Related Questions