Skip to content

Instantly share code, notes, and snippets.

@mrkline
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrkline/f38e87670422b652723d to your computer and use it in GitHub Desktop.
Save mrkline/f38e87670422b652723d to your computer and use it in GitHub Desktop.
Why Exceptions?

Exceptions are used over return codes/errnos to handle errors, as they are the idiomatic error handling mechanism in modern C++ code.

  • First and foremost, an uncaught exception exits the program. This is a Good Thing™. Exceptions should only be thrown in the first place when an problem occurs that cannot be handled in the current scope. If this problem is not handled at some scope above the current one, the program should exit, regardless of what error handling paradigm is being used. When using error codes, you can forget to check the returning code. If this occurs, the program hobbles along in some undefined zombie state until it crashes or misbehaves some number of calls down the road, producing the same result but giving you a debugging nightmare.
  • Not using error codes allows you to actually use the return value to return the output of the called function instead of using "output" parameters by passing pointers or references. This produces arguably cleaner code.
  • Some places, such as constructors, cannot return error codes. Trying to shoehorn an error code into a constructor means
    1. You have to use an "output" parameter to return the error code (ew).
    2. Your class can exist in some zombie state if the constructor fails. Compare this to using exceptions, where a throw in the constructor means the object never existed in the first place.
    3. Having a two-phase init where the constructor does little to nothing and initialization is handled by an init() function returns you to point 2. (You can now be in a zombie "declared but uninitialized" state.)
  • Exceptions avoid cluttering up your logic with constant checks to see if functions succeeded. In a way it is a separation of concerns: logic goes in the try block and error handling goes in the catch block.
  • Modern exception implementations are extremely cheap in performance cost, and in some cases even free until an exception is thrown. Checking error codes of every call is not free either, so performance-based arguments against exceptions are anachronisms.
  • A common criticism of exceptions is that they allow functions to exit at arbitrary points instead of just at provided return statements. If RAII is being properly used, this point is moot. Destructors will automatically clean up any local resources as the call stack unwinds.

The only time exceptions are not appropriate is on hard-real-time systems like avionics software where the time taken to throw and catch an exception cannot be guaranteed (see Stroustrup's page).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment