Exceptional wisdom

In Visual C++ 7.1 and earlier, "catch(...)" would catch all exceptions, both C++ and SEH. The behavior has changed with Visual C++ 8.0. This has caused some confusion.

The details get a bit tricky, but the generally accepted wisdom among the C++ gurus that have advised me is:

  1. try/catch is for C++ exceptions.
    • Corollary: Don't catch C++ exceptions with __except.
  2. __try/__except is for Windows Structured Exception Handling (SEH) exceptions.
    • Corollary: Don't catch SEH exceptions with catch.
    • Corollary: Don't use _set_se_translator. Use __except, then throw your C++ exception from the __except block.
    • Corollary: Don't use /EHa. The only reason to use /EHa is to catch SEH exceptions with catch or via _set_se_translator, which you shouldn't be doing in the first place.
  3. Don't use both C++ exception handling and SEH exception handling in the same function.
    • Creating an instance of an object that has a destructor implicitly generates a try/catch block, so don't create destructable objects in a function that uses __try/__except or might directly raise an SEH exception.
  4. Don't catch anything you don't know how to handle.
  5. You don't know how to handle Access Violations.
    • Corollary: Don't catch Access Violations. Ever.
  6. It was always kind of weird (many would say horrible and bad) that the C++ catch would sometimes catch SEH exceptions. This was never dependable. Don't rely on this behavior.
  7. It is a compiler implementation detail that __except can catch C++ exceptions. Don't rely on this behavior.
  8. Visual C++ 8.0 changed the semantics of "catch(...)".
    • catch(...) no longer catches all SEH exceptions. This is a good thing (see rules 4 and 5).
    • If you were following the above rules, you didn't see any changes in your program's behavior.