-3

I have the following code snippet:

#include<iostream>
using namespace std;

class Test {

public:

    Test()  { cout << "Constructor is executed\n"; }
    ~Test() { cout << "Destructor is executed\n";}
    void show()  {  this->Test::~Test(); }
};

int main() {

    Test t;
    t.show();
    return 0;
}

Here is the output:

Constructor is executed
Destructor is executed
Destructor is executed

Question: If t.show() has already called the destructor on "this" object(i.e. current object), which causes "destructor is executed" to be displayed once, then what causes it to be displayed for the second time? Which object is getting destroyed in that case ?

Pradhan
  • 16,391
  • 3
  • 44
  • 59
  • Why are you wondering, if you call the destructor explicitely here: `this->Test::~Test();`? You should never do such BTW. – πάντα ῥεῖ Mar 30 '15 at 03:13
  • 2
    The second time it would be called, [undefined behaviour](http://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) is triggered – M.M Mar 30 '15 at 03:14
  • 1
    I think the question is OK. Ofc, it would trigger UB, and ofc one should not call destructor explicitly, but the question is when and why it's called second time. It's essentially the same as removing explicit call and asking where was it called at all. – luk32 Mar 30 '15 at 03:17

2 Answers2

8

Automatic variables get destroyed when they go out of scope. Test t is an automatic variable which goes out of scope when main ends. That's the second time the destructor is being called. The first time is through Test::show since the function manually destroys the object pointed to by this.

Since, C++ follows the philosophy of not paying for what you don't use, there isn't a runtime check of any sort before invoking the destructor on automatic variables going out of scope. Of course, what actually happens on the second destructor call is UB. Beware of nasal demons.

Pradhan
  • 16,391
  • 3
  • 44
  • 59
3

Pradhan has given you an easy to understand explanation, I'll share the particular rule that deals with explicit destructor calls on objects with automatic storage duration, found in section 3.8p8 of the Standard:

If a program ends the lifetime of an object of type T with static, thread, or automatic storage duration and if T has a non-trivial destructor, the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined. This is true even if the block is exited with an exception.

You're violating this rule, so you get undefined behavior.

The "implicit destructor call" is described in 6.7p2:

Variables with automatic storage duration are initialized each time their declaration-statement is executed. Variables with automatic storage duration declared in the block are destroyed on exit from the block.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720