We present mechanisms that enable our compiler-target language, C--, to exp
ress four of the best known techniques for implementing exceptions, all wit
hin a single, uniform framework. We define the mechanisms precisely, using
a formal operational semantics. We also show that exceptions need not requi
re special treatment in the optimizer; by introducing extra dataflow edges,
we make standard optimization techniques work even on programs that use ex
ceptions. Our approach clarifies the design space of exception-handling tec
hniques, and it allows a single optimizer to handle a variety of implementa
tion techniques. Our ultimate goal is to allow a source-language compiler t
he freedom to choose its exception-handling policy, while encapsulating the
architecture-dependent mechanisms and their optimization in an implementat
ion of C-- that can be used by compilers for many source languages.