0

I wrote a small script to test copy elision in C++:

#include<iostream>
using namespace std;

class Test{
public:
  int m;
  Test(int x = 0): m(x) { cout << "constructing!" << endl;}
  Test(const Test& t): m(t.m) { cout << "copy constructing!" << endl;}
};

Test function_1(Test& t){
  Test x;
  cout << "testing_1" << endl;
  return x;
}

Test function_2(Test t){
  cout << "testing_2" << endl;
  return t;
}

Test function_3(Test t){
  cout << "testing_3" << endl;
  return t;
}

int main(){
  Test t(5);
  cout << "main_1" << endl;
  function_1(t);
  cout << "main_2" << endl;
  function_2(t);
  cout << "main_3" << endl;
  function_3(Test(6));
  cout << "Done" << endl;
  return 0;
}

This program prints (changing the C++ version from 11 to 14 to 17 didn't change the output by the way):

$ ./a
constructing!
main_1
constructing!
testing_1
main_2
copy constructing!
testing_2
copy constructing!
main_3
constructing!
testing_3
copy constructing!
Done

I'm having a tough time interpreting these results. It is unclear to me when and why the compiler would choose to call the copy constructor in some instances and not in others, especially in the context of classes being passed and returned as arguments to functions. When and why is the copy constructor called?

user308485
  • 611
  • 1
  • 5
  • 25
  • Why do you have `function_2` and `function_3`? – Holt Jun 18 '19 at 07:21
  • I couldn't understand why the copy constructor is being called when function_2 returns – user308485 Jun 18 '19 at 07:22
  • If you want to understand a bit more you can 1) Add a move constructor to `Test` (`Test(Test &&)`), and compile with `-fno-elide-constructors`). – Holt Jun 18 '19 at 07:27
  • Your code does not test copy elision. – Nikos C. Jun 18 '19 at 07:29
  • This might also be good to read through for the concepts rather than what the standard says: https://stackoverflow.com/questions/6009278/why-are-by-value-parameters-excluded-from-nrvo – chris Jun 18 '19 at 07:29

0 Answers0