StackUser2015
StackUser2015

Reputation: 1

Extra destructor in Constructor, Copy constructor, Destructor sequence in C++

I am learning C++ and am new to StackOverflow. For a test code, I am observing an extra destructor call relative to what I was expecting. Below is the code followed by my expected output followed by the actual output.

Code:

#include <iostream>

class c_Test {
  public:
    c_Test() { std::cout << "Constructor" << std::endl; }
    c_Test(const c_Test& x_in) { std::cout << "Copy constructor" << std::endl; }
    c_Test operator= (const c_Test&) { std::cout << "operator =" << std::endl; }
    ~c_Test() { std::cout << "Destructor" << std::endl; }

};

int main()
{
  c_Test t0, t1;  // call constructor, constructor
  c_Test t2 = t0;       // call copy constructor
  t0 = t1;              // call operator=

  return 0; // should call destructor, destructor, destructor
}

I expected the output to be:

Constructor
Constructor
Copy constructor
operator =
Destructor
Destructor
Destructor

What I get after compiling and running the program:

Constructor
Constructor
Copy constructor
operator =
Destructor
Destructor
Destructor
Destructor

I expected every destructor to be paired with a constructor but that is not the case. Why is there an extra Destructor?

Upvotes: 0

Views: 103

Answers (1)

Wintermute
Wintermute

Reputation: 44073

Your operator= declares a return type but doesn't return anything; this causes undefined behavior. If you change it to

c_Test &operator= (const c_Test&) {
  std::cout << "operator =" << std::endl;
  return *this;
}

then you get the behavior you expect.

Side note: This is outside the language specification and as such not dependable, but it seems reasonable to suspect that your compiler inserts a destructor call because the operator= you declared looks from the outside as though it returned a temporary value (i.e., as though it had constructed an object that required destruction), and that no corresponding constructor call is inserted because the operator= doesn't make good on this promise of its declaration.

Indeed, just declaring the operator= as returning a reference and not inserting the return statement makes the code, compiled with gcc 4.9 (without optimizations), show the expected behavior. Compiled with clang it crashes, as is its right.

Upvotes: 4

Related Questions