Wary of Exception Handling in C++?
June 17, 2019
The Exception Handling System (EHS) in C++ has absolutely nothing to be with exceptions in the sense of being hardware interrupts.
The C++ has been slow to take off among embedded developers. Although many engineers are enthusiastic, many are very pragmatic and take an “if it ain’t broke, don’t fix it” approach and stick with C. Often there is concern about one specific feature; commonly that feature is exception handling.
The Exception Handling System (EHS) in C++ has absolutely nothing to be with exceptions in the sense of being hardware interrupts. It is designed to handle exceptional situations that are detected by the software. The intention is to provide a controlled failure mode, where a smooth exit from some deeply nested function calls is required (without resorting to goto).
The use of the EHS is reasonably straightforward. Code that needs EHS activated during its execution is enclosed in a try block. A throw statement is used to assert an exception, which is identified by means of a class. Processing of the exception is performed by some code in a catch block. There is normally one catch block for each type of exception (i.e. each identifying class) that may be asserted.
This does seem fairly neat and simple and does provide a way to write fairly readable code in which exception handling is needed. However, there are some key points that cause justified concern to embedded software developers:
- If you are going to use the EHS, the additional code must be incorporated (a compiler switch) for the entire application. It is not obvious to the human reader (or the compiler) what functions might be called directly or indirectly by the code in a try block. This additional code adds size and reduces execution performance.
- Many compilers default to including EHS code. This means that the unwitting user incorporates the overhead automatically, even if they have no intention of using the EHS. A compiler switch is normally available to activate or deactivate the EHS code generation.
- If your application's exception handling needs are simple, there are two ways to deploy the EHS that reduce the overheads:
- Use a generic catch block [where the type is specified with "..."] instead of one for each type of exception.
- Do not include any catch blocks. This results in the library function terminate() being called when an exception is thrown. This function can be customized.
There are strong arguments for not using the EHS. However, used with care, it may be beneficial to many designs. The overhead should be anticipated and carefully measured at the earliest opportunity so that it does not cause problems at a later stage of development.