Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does explicitly calling destructor result in Undefined Behavior here?

In my opinion, the following code (from some C++ question) should lead to UB, but the it seems it is not. Here is the code:

#include <iostream>
using namespace std;
class some{ public: ~some() { cout<<"some's destructor"<<endl; } };
int main() { some s; s.~some(); }

and the answer is:

some's destructor
some's destructor

I learned form c++ faq lite that we should not explicitly call destructor. I think after the explicitly call to the destructor, the object s should be deleted. The program automatically calls the destructor again when it's finished, it should be UB. However, I tried it on g++, and get the same result as the above answer.

Is it because the class is too simple (no new/delete involved)? Or it's not UB at all in this case?

like image 774
EXP0 Avatar asked Jul 20 '10 15:07

EXP0


1 Answers

The behavior is undefined because the destructor is invoked twice for the same object:

  • Once when you invoke it explicitly
  • Once when the scope ends and the automatic variable is destroyed

Invoking the destructor on an object whose lifetime has ended results in undefined behavior per C++03 §12.4/6:

the behavior is undefined if the destructor is invoked for an object whose lifetime has ended

An object's lifetime ends when its destructor is called per §3.8/1:

The lifetime of an object of type T ends when:

— if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or

— the storage which the object occupies is reused or released.

Note that this means if your class has a trivial destructor, the behavior is well-defined because the lifetime of an object of such a type does not end until its storage is released, which for automatic variables does not happen until the end of the function. Of course, I don't know why you would explicitly invoke the destructor if it is trivial.

What is a trivial destructor? §12.4/3 says:

A destructor is trivial if it is an implicitly-declared destructor and if:

— all of the direct base classes of its class have trivial destructors and

— for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.

As others have mentioned, one possible result of undefined behavior is your program appearing to continue running correctly; another possible result is your program crashing. Anything can happen and there are no guarantees whatsoever.

like image 62
James McNellis Avatar answered Oct 10 '22 04:10

James McNellis