As a follow-up to my previous question:
If I change the code as follows:
struct ExceptionBase : virtual std::exception{};
struct SomeSpecificError : virtual ExceptionBase{};
struct SomeOtherError : virtual ExceptionBase{};
void MightThrow();
void HandleException();
void ReportError();
int main()
{
try
{
MightThrow();
}
catch( ... )
{
HandleException();
}
}
void MightThrow()
{
throw SomeSpecificError();
}
void HandleException()
{
try
{
throw;
}
catch( ExceptionBase const & )
{
// common error processing
}
try
{
throw;
}
catch( SomeSpecificError const & )
{
// specific error processing
}
catch( SomeOtherError const & )
{
// other error processing
}
try
{
ReportError();
}
catch( ... )
{
}
}
void ReportError()
{
throw SomeOtherError();
}
The “last handler” for the original exception (i.e. the one in main) has not exited when the second exception is thrown, so are both exceptions active? Is the original exception still available once we leave the handler for the second exception?
C++11 (N3242):
(
std::exception_ptris a C++11 feature, and isn’t used in your example code.)Or equivalently, I think,
throw;always refers to the exception caught by the innermost catch block which is currently executing. Except that I haven’t defined ‘innermost’ and ‘executing’ as carefully as the Standard defined all its terms above.And yes, more than one exception object can be allocated at a time, and C++ is required to make sure they live long enough to do “the right thing” when you try to rethrow.