uC++ EHM

Derived Exception-Type

Derived exception-types let exception types inherit from each other, just like class inheritance β€” providing polymorphism across exception types.

Why do we want an exception hierarchy?

Because different callers want different degrees of specificity. Low-level I/O code knows it’s a File error; a high-level retry loop only cares that some IO error happened. Inheritance lets the same raise be caught at any level of the hierarchy, so higher-level code can couple to IO rather than File and not break when the underlying implementation changes.

Hierarchy shape (from the notes)

                    Exception
                   /         \
                  IO         Arithmetic
                 /  \       /     |      \
              File  Network DivByZero Overflow Underflow

Matching rules

  • A handler for a base type catches any derived type.
  • Most propagation mechanisms do a linear search of the handlers in a guarded block β€” so order matters:
try { ... }
catch( Arithmetic & ) { ... }
catch( Overflow ) { ... }   // NEVER selected β€” Arithmetic catches it first
  • Higher-level code should catch general types to reduce tight coupling to specific implementations (tight coupling forces churn in higher-level code when low-level code changes).

Catch by reference when subclassing

struct B {};
struct D : public B {};
try {
    throw D();
} catch( B e ) {                  // TRUNCATION β€” e is a B now, cannot down-cast
    ...
}
try {
    throw D();
} catch( B & e ) {                // no truncation β€” can dynamic_cast<D>(e)
    ... dynamic_cast<D&>(e) ...
}

By value, the exception is truncated from its dynamic type to the static type at the handler. By reference, the dynamic type is preserved and down-casting works.

uC++ doesn't truncate on raise

Catching truncation (above) is different from raising truncation. In uC++, _Throw raises the original object of type D even when a function parameter was declared as base B β€” so handlers can catch the specific derived type, not the base. This is the _Throw t row in the EHM table.