I am not getting why if there is an active exception then if an exception is raised again, it leads to termination of program. Could someone explain?
views:
204answers:
6What is it suppose to do? It can't "double catch" or anything, nor does it make sense to simply ignore one. The standard specifies that if, during stack unwinding, another exception escapes, then terminate
shall be called.
There is more discussion in the C++ FAQ. One "solution" is to wrap your destructor code in a try/catch block, and simply don't let exceptions escape.
Another is to come up with some sort of custom exception chaining scheme. You'd do the above, but instead of ignoring an exception, you would append it to the currently thrown exception, and at the catch site handle both by hand.
The best solution, I think, it to try to remove the exceptional code from your destructor.
The reason is simple... if an exception is thrown during exception propagation, then which exception should be propagated? The original exception or the new exception? If the new exception is propagated and then handled, how will the program know that the other exception occurred? Or will the original exception be ignored? This and many other complications lead to the simple rule that only one exception may be propagated at a time, and multiple failures will result in the application being terminated.
This post has an explanation of the problem: http://web.tiscali.it/fanelia/cpp-faq-en/exceptions.html#faq-17.3
When you throw
an exception, it keeps unwinding the stack until it reaches an appropriate catch
block. As part of the stack unwinding process, destructors are called for every object in each frame's scope.
Now, when a destructor throws an exception in this case, there's a dilemma -- which catch
block is the program supposed to stop at? The original exception, or the new exception? Either way, there's an unprocessed exception involved.
Program's aren't good at making decisions like this, so the standard says it won't even try to resolve the issue and just gives up.
Check out the FAQ-Lite entry explaining this exact situation for further details.
Quoth the standard (15.2.3):
The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called ``stack unwinding.'' [Note: If a destructor called during stack unwinding exits with an exception, terminate is called (except.terminate). So destructors should generally catch exceptions and not let them propagate out of the destructor. --- end note]
Basically C++ (as most other popular programming languages) has no good support for handling multiple errors using exceptions. Exceptions, as a mechanism, is simply deficient in that respect.
The FAQ has some suggestion on How to handle a destructor that fails?
Stroustroup has this to say on the matter (TCPL 14.7):
The reason for terminate() is that exception handling must occasionally be abandoned for less subtle error-handling techniques. For example, terminate() could be used to abort a process or maybe to re-initialize a system. The intent is for terminate() to be a drastic measure to applied when the error-recovery strategy implemented by the exception-handling mechanism has failed and it is time to go to another level of a fault tolerance strategy.
See also previous related discussion on SO: basically any question about exceptions and destructors.
Item 8
of Effective C++ says that you shouldn't ever allow an exception to leave a destructor.