C++ Exceptions

As I get ready to code in C++ again full time, I was wondering about the cost of exceptions. It turns out that it costs you nothing at run time to have exception handling in your code unless you actually throw/catch them.

The compiler creates a table. It puts an entry point in the table for all exception handlers. The only potential cost to your code is that this exception handler may modify the logical flow of your function, causing the need for an additional jmp to get around it. More likely, the code will be put at the end of your function, and the jmp will be from within the exception handling code to the next instrcution instruction. For example:

#include <exception>
int a(){
int i = 0;
throw i;
}

int main(){
try{
a();
}catch(int i){

}
return 0;
}

Now the catch block doesn’t do anything here, but it will stop the exception from propagating. The return statement has to be called regardless of whether the catch block is entered. Here’s the result of compiling and then disassembling. site analysis . Note that the functino called ‘a’ about has its name mangled to _Z1av.

0000000000400758 <main>:
400758: 55 push %rbp
400759: 48 89 e5 mov %rsp,%rbp
40075c: 48 83 ec 10 sub $0x10,%rsp
400760: e8 c3 ff ff ff callq 400728 <_Z1av>
400765: eb 26 jmp 40078d <main+0x35>
400767: 48 89 45 f0 mov %rax,0xfffffffffffffff0(%rbp)
40076b: 48 83 fa 01 cmp $0x1,%rdx
40076f: 74 09 je 40077a <main+0x22>
400771: 48 8b 7d f0 mov 0xfffffffffffffff0(%rbp),%rdi
400775: e8 be fe ff ff callq 400638 <_Unwind_Resume@plt>
40077a: 48 8b 7d f0 mov 0xfffffffffffffff0(%rbp),%rdi
40077e: e8 a5 fe ff ff callq 400628 <__cxa_begin_catch@plt>
400783: 8b 00 mov (%rax),%eax
400785: 89 45 fc mov %eax,0xfffffffffffffffc(%rbp)
400788: e8 6b fe ff ff callq 4005f8 <__cxa_end_catch@plt>
40078d: b8 00 00 00 00 mov $0x0,%eax
400792: c9 leaveq
400793: c3 retq

Notice the calls are to begin_catch, unwind_resume, end_catch etc are all boilerplate exception handling code. The jmp at address 400765 skips over all of this and goes right to the return code at address 40078d.

What this means is that for code that does not throw an exception, there is no cost in the calling function. The runtime cost of exception handling may be high if an exception is thrown. Thus, exception handling should not be in the default path, merely the exceptional.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.