I have a code such as this:
class myclass
{
myclass()
{
// doing some init here
}
~myclass()
{
// doing some important clean up here
}
void Do()
{
// doing some work which may throw exception
}
}
and I am using this class in this way:
MyFunction()
{
myclass mc;
mc.do();
}
My question is :
If there is an exception in do function, what would happen? Is destructor of myclass called?
If no, what is the best way to handle this type of situations? Assume that I don't have the source code and I am sure about what is happening in destructor.
If there is an exception in do function, what would happen?
If you have any handler, it will be handled.
Is destructor of myclass called?
Yes, definitely. The standard quotes this::
An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object has completed execution and a delegating constructor for that object exits with an exception, the object’s destructor will be invoked. If the object was allocated in a new-expression, the matching deallocation function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.
This whole process is known as "stack unwinding":
The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called “stack unwinding.” If a destructor called during stack unwinding exits with an exception, std::terminate is called (15.5.1).
C++11 15.5.1 The std::terminate() function [except.terminate]
2 … In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std::terminate() is called.
If the exception is caught somewhere, then stack unwinding will guarantee that the destructor is called for this object (and, in general, all automatic variables that go out of scope as a result of the exception). This is a very important guarantee, without which we could not use techniques like RAII to write exception-safe code.
If the exception is not caught, then the program will be terminated, and it's implementation-dependent whether or not the stack will be unwound first. If it's important to destroy the object cleanly even in that situation, then one option is to catch and rethrow the exception, outside the object's scope.
If the program is ended in some other way, e.g. by calling exit()
or terminate()
, or receiving an unhandled signal, then the stack won't be unwound. If you need clean destruction in these situations, then things will get messy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With