uC++ EHM

Dynamic Propagation

Dynamic propagation resolves the handler at runtime β€” the raise walks the call stack looking for a matching guarded block. It covers cases 3 and 4 of the call/return table:

return \ raisestatic calldynamic call
static1) sequel3) termination exception
dynamic2) routine4) routine pointer, virtual routine, resumption

Why pay for dynamic lookup when sequels are cheaper?

Because dynamic propagation works for separately-compiled programs β€” a library can raise an exception without knowing who will catch it. The cost is that the handler isn’t statically known, so the same raise-site action runs for every exceptional control-flow change. That’s the tradeoff: lose compile-time knowledge, gain modularity.

Termination (case 3)

Dynamic raise, static return β€” also called dynamic multi-level exit (DME).

  • Control transfers from the raise to the handler β‡’ dynamic raise (call).
  • When the handler returns, it performs a static return β‡’ stack is unwound (like sequel).
  • See Termination.

Resumption (case 4)

Dynamic raise, dynamic return.

  • Control transfers from raise to handler β‡’ dynamic raise (call).
  • Handler returns dynamically β‡’ stack is NOT unwound (like a routine).
  • See Resumption.

Why dynamic is the default for library code

Sequels fail when stack is separately compiled because the sequel call in push no longer knows the static blocks containing calls to it. Dynamic propagation sidesteps this entirely β€” the raise site names only the exception type, and the runtime finds the first matching handler on the stack.