g++ compiler has the feature of zero-cost exception handling. To my understanding, try
does nothing, but when exception is thrown, a subroutine for the exception handler is executed. Like this:
void foo() {
try {
bar(); // throws.
} catch (Type exc) {
baz();
}
}
In pseudocode (c-stylish) would look like this:
void foo() {
bar();
return;
catch1_Type:
baz();
}
bar() throws. The exception routine does the following:
Ah, the return address is in function foo()! And the return address is in the first try-catch block, and we throw type Type, so the exception handler routine is at address foo+catch1_Type. So cleanup the stack so we end up there!
Now my question: is there any way to implement it in C? (Can be C99 or newer, although I'm interested in C dialect supported by gcc). I know that I can use e.g libunwind for stack examination and traversal, although I have no idea how to get the address of catch1_Type
label. It may not be possible.
The exception handler may be a different function, that's equally OK, but then how to get addresses of local variables of stackframe foo
in that other function? It also seem to be impossible.
So... is there any way to do it? I would like not to go into assembler with this, but it also is acceptable if everything else fails (although local variables - man, you never know where they are if using different optimization levels).
And to be clear - the purpose of this question is to avoid setjmp/longjmp approach.
EDIT: I've found a quite cool idea, but does not work entirely:
Nested functions in gcc. What they can do?
- have access to local variables,
- have possibility to goto local labels in the parent function!
- can be called by callees of our function, provided that we pass a pointer to the nested function, so it's available by pointer in the callee.
Downside which prevents me from doing anything zero-cost:
- they're optimized out even at -O0 level if they're unused. Can I do anything about this? If I could, I could get address by symbol name when exception is thrown and it would simply do the job of implementing exceptions which cost nohing when not thrown...