Only one exception can be evaluated at a time. From 15.1 / 7
If the mechanism for handling exceptions, after evaluating the expression being completed, but before the exception is caught, calls a function that leaves the exception, std :: terminate is called.
In your example, std::terminate() not called, because in fact only one exception is thrown. When throw throw_it(); reached throw throw_it(); , throw_it() is evaluated first, which causes the function to be called before the exception is actually thrown. Since the function throws an exception and never returns the original throw , it will never be reached. If throw_it() does not throw an exception and returns an integer value, then the throw expression will be executed. Therefore, for your example, foo guaranteed to be printed.
But what about throwing a new exception from the active handler? When an exception is caught, it has been fully evaluated. When you throw a new exception (instead of throwing it with a throw), the original exception is destroyed and the evaluation of the new exception begins.
From 15.1 / 4
The exception object is destroyed after the last remaining active handler for the exception exits by any means other than re-creating or ....
This satisfies the rule that only one exception can be evaluated at a time.
Captain obvlious
source share