uC++ EHM

Multiple Exceptions

An exception handler can generate an arbitrary number of nested exceptions, but multiple exceptions cannot propagate simultaneously. Nesting is fine; concurrent propagation is not.

Why can nesting work but simultaneous propagation can't?

Nesting is sequential — the inner catch runs to completion before the outer raise happens. Simultaneous propagation would mean two unwinds at once, and the runtime has no way to pick which catch handles which without losing one. So the rule is: at most one exception propagating at a time.

Nested raise inside a handler

struct E {};
int cnt = 3;
void f( int i ) {
    if ( i == 0 ) throw E();
    try {
        f( i - 1 );
    } catch( E ) {              // handler h
        cnt -= 1;
        if ( cnt > 0 ) f( 2 );  // raise inner E during outer handling
        ... throw; ...
    }
}
int main() { f( 2 ); }

Call trace: h catches inner throw → the body of h rethrows or throws a new E that propagates up through the next f frame → caught at the next outer h.

The simultaneous-propagation rules

  • Cannot start a second exception without a handler to deal with the first (can’t drop).
  • Cannot postpone the first because the second could remove its handlers while unwinding.
  • Only destructor code can intervene during propagation — and even then, the destructor can only start a new propagation, not raise during one.

Detecting an in-flight exception

try {
    C x;                // C::~C is noexcept(false) and raises on deallocation
    throw E();          // starts propagation
} catch( E ) { ... }

When throw E() unwinds, x’s destructor wants to raise E too. Use uncaught_exceptions() inside the destructor to check if an exception is already being propagated, and skip the raise when it is.