Is the following well-defined in C++, or not? I am forced to ‘convert’ exceptions to return codes (the API in question is used by many C users, so I need to make sure all C++ exceptions are caught & handled before control is returned to the caller).
enum ErrorCode {…};
ErrorCode dispatcher() {
try {
throw;
}
catch (std::bad_alloc&) {
return ErrorCode_OutOfMemory;
}
catch (std::logic_error&) {
return ErrorCode_LogicError;
}
catch (myownstdexcderivedclass&) {
return ErrorCode_42;
}
catch(...) {
return ErrorCode_UnknownWeWillAllDie;
}
}
ErrorCode apifunc() {
try {
// foo() might throw anything
foo();
}
catch(...) {
// dispatcher rethrows the exception and does fine-grained handling
return dispatcher();
}
return ErrorCode_Fine;
}
ErrorCode apifunc2() {
try {
// bar() might throw anything
bar();
}
catch(...) {
return dispatcher();
}
return ErrorCode_Fine;
}
I hope the sample shows my intention. My guess is that this is undefined behaviour, but I’m not sure. Please provide quotes from the standard, if applicable. Alternative approaches are appreciated as well.
Thanks!
That’s fine. The exception is active until it’s caught, where it becomes inactive. But it lives until the scope of the handler ends. From the standard, emphasis mine:
That is:
Between those arrows, you can re-throw the exception. Only when the handlers scope ends does the exception cease to exist.
Keep in mind if you call
dispatchwithout an active exception,terminatewill be called. Ifdispatchthrows an exception in one if it’s handlers, that exception will begin to propagate. More information in a related question.