Boost.Container and C++ exceptions

| Home | Libraries | People | FAQ | More

## Boost.Container and C++ exceptions

In some environments, such as game development or embedded systems, C++ exceptions are disabled or a customized error handling is needed. According to document N2271 EASTL -- Electronic Arts Standard Template Library exceptions can be disabled for several reasons:

- “Exception handling incurs some kind of cost in all compiler implementations, including those that avoid the cost during normal execution. However, in some cases this cost may arguably offset the cost of the code that it is replacing.”
- “Exception handling is often agreed to be a superior solution for handling a large range of function return values. However, avoiding the creation of functions that need large ranges of return values is superior to using exception handling to handle such values.”
- “Using exception handling correctly can be difficult in the case of complex software.”
- “The execution of throw and catch can be significantly expensive with some implementations.”
- “Exception handling violates the don't-pay-for-what-you-don't-use design of C++, as it incurs overhead in any non-leaf function that has destructible stack objects regardless of whether they use exception handling.”
- “The approach that game software usually takes is to avoid the need for exception handling where possible; avoid the possibility of circumstances that may lead to exceptions. For example, verify up front that there is enough memory for a subsystem to do its job instead of trying to deal with the problem via exception handling or any other means after it occurs.”
- “However, some game libraries may nevertheless benefit from the use of exception handling. It's best, however, if such libraries keep the exception handling internal lest they force their usage of exception handling on the rest of the application.”

In order to support environments without C++ exception support or environments with special error handling needs, Boost.Container changes error signalling behaviour when `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` or `BOOST_NO_EXCEPTIONS` is defined. The former shall be defined by the user and the latter can be either defined by the user or implicitly defined by Boost.Confg when the compiler has been invoked with the appropriate flag (like `-fno-exceptions` in GCC).

When dealing with user-defined classes, (e.g. when constructing user-defined classes):

- If `BOOST_NO_EXCEPTIONS` is defined, the library avoids using `try`/`catch`/`throw` statements. The class writer must handle and propagate error situations internally as no error will be propagated through Boost.Container.
- If `BOOST_NO_EXCEPTIONS` is not defined, the library propagates exceptions offering the exception guarantees detailed in the documentation.

When the library needs to throw an exception (such as `out_of_range` when an incorrect index is used in `vector::at`), the library calls a throw-callback declared in `boost/container/throw_exception.hpp`:

- If `BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS` is defined, then the programmer must provide its own definition for all `throw_xxx` functions. Those functions can't return, they must throw an exception or call `std::exit` or `std::abort`.
- Else if `BOOST_NO_EXCEPTIONS` is defined, a `BOOST_ASSERT_MSG` assertion is triggered (see Boost.Assert for more information). If this assertion returns, then `std::abort` is called.
- Else, an appropriate standard library exception is thrown (like `std::out_of_range`).