Issue
We know that terminate
() is called if an exception is currently active and there is another call to throw
.
Want to understand what causes this to be differentiated from a situation when a catch
block does a throw
from with-in? I am assuming that a if a catch
block is executing, it signifies of an active exception.
class exception_type{}
try{ ... throw obj; ...
}catch(exception_type& obj){
...
...
throw x;
...
}
From this code sample, since we have another throw
here in catch
block, which should get caught by another handler in the dynamically enclosing try
block.
So this seems to be a valid use of a throw
inside catch
. But at this moment we already have a an exception active. Why should not it cause terminate
() to be called? Or in other words, how exactly the gcc's c++ runtime would recognize that there is already an exception active and a terminate
() needs to be called.
Solution
The credit for this answer goes to @HolyBlackCat who has hinted this in his answer.
The response of a throw
is a complex process in which C++ run-time needs to perform several distinct actions. Though the actual process may be defined by run-time's implementation but few things could be understood in common. This paper could shed some more light. Please see section 3.3.
In the process of servicing a throw
, a search for appropriate catch
is initiated. This in itself may cause unwinding of the current stack frame. The side effect of unwinding a stack frame is that corresponding destructors for objects in current frame be called. This action of calling a destructor again lands run-time in user's code area(unsafe). After this is done, we again enter in the run-time's territory(safer).
Finally when a suitable catch
is entered, the active exception is destroyed and it starts executing handler's code. For this reason the throw
as shown in question, would not experience any active exception.
This also explains why we should not throw
an exception from a destructor which goes out of scope. It would actually be a good practice to have a try{....}catch(...)
block in destructor to safeguard from any untoward terminate
() incidents.
Answered By - ultimate cause