What would be the right way to generate a C++ API for old C code that is extensively using longjmp with multiple jump targets for error management?
My idea was to write a function that sets jump targets for each used target, e.g.:
void catchJumps() {
if (setjmp(target1)) throw Error1(); //Error1 and Error2 are some exception classes
if (setjmp(target2)) throw Error2();
//...
}
Then I'd call catchJumps
in each C++-function (in each scope, to be more specific) that is using the C code:
int some_wrapper() {
catchJumps();
callCFunction()
for (int i = 0; i < 1000; i++) {
catchJumps();
callOtherCFunction();
}
catchJumps();
callOneMoreCFunction();
callEvenOneMoreCFunction();
}
Is this a safe way to catch all the longjumps without destroying the stack? I know, that it's dangerous to longjmp into a different stack frame. Now my function catchJumps
is in another stack frame than the calling some_wrapper
. I'd hope (or can I even make it to) catchJumps can be inlined, so that the frame is the same, but I don't know.
The call in each scope (and after the loop above) should be necessary for all destructors of scoped objects to be called, right?
If this is not a valid method for 'converting' longjmps to assertions for the calling application, what else can we do?
You might have problems when using
catchJumps
with automatic objects that have destructors as explained in https://stackoverflow.com/a/1376099/471164 and citing 18.7/4 "Other runtime support":I think a better approach is to create a wrapper for each C function that you use and that can do
longjmp
translating all these non-local gotos into exceptions. This will also make your code cleaner because you won't havecatchJumps()
all over the place but only in these wrapper functions.