As I continue with my current pre-occupation with C++, I decided to discuss some aspects of the language with my colleague Jonathan Roelofs, who is a development tools specialist. Like me, Jonathan is particularly interested in the tools issues that concern embedded developers.
As it seems to have wide interest, I decided to explore exception handling …
I have a concern about the overhead of extra code which is incorporated if exception handling is activated. I asked Jonathan: “Are there a number of possibilities for ways that EHS may be implemented, each of which affect the overhead in a different way?”
There are so-called “zero cost” exception handling implementations where there is no runtime penalty when an exception is not thrown (you only pay for it in code size for the exception handling tables, and in execution time while unwinding between the throw and the catch). This differs from Setjmp-Longjmp [SjLj] exception handling where you always pay for it in both code size (for the EH tables), and execution time (saving all the registers on entry to the try block). SjLj tends to be faster at unwinding, but slower in the general case. The tradeoff really depends on which scenario the toolchain and OS provider expects to be more likely.
A further question: “Given that the developer has got some tools and cannot change how EHS is implemented, what can he do to minimize overhead?”
Apart from the two ways that you suggested (generic catch block or none at all), there is also a third way to help cut down on overhead: use the noexcept keyword or the nothrow attribute. These can be used when you know that, dynamically, a function and its callees will never throw something that is expected to be caught by the function’s caller. In practice, they cut down on the extra code size needed for the unwind tables for those functions.
I am sure that I will be reporting on further conversations here in the weeks to come. If you have any questions, be sure to email or comment.