Does Throw Inside a Catch Ellipsis (...) Rethrow the Original Error in C++

Does throw inside a catch ellipsis (...) rethrow the original error in C++?

Yes. 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:

§15.1/4: The memory for the temporary copy of the exception being thrown is allocated in an unspecified way, except as noted in 3.7.4.1. The temporary persists as long as there is a handler being executed for that exception.

That is:

catch(...)
{ // <--

/* ... */

} // <--

Between those arrows, you can re-throw the exception. Only when the handlers scope ends does the exception cease to exist.

In fact, in §15.1/6 the example given is nearly the same as your code:

try {
// ...
}
catch (...) { // catch all exceptions
// respond (partially) to exception <-- ! :D
throw; //pass the exception to some
// other handler
}

Keep in mind if you throw without an active exception, terminate will be called. This cannot be the case for you, being in a handler.


If doSomethingElse() throws and the exception has no corresponding handler, because the original exception is considered handled the new exception will replace it. (As if it had just thrown, begins stack unwinding, etc.)

That is:

void doSomethingElse(void)
{
try
{
throw "this is fine";
}
catch(...)
{
// the previous exception dies, back to
// using the original exception
}

try
{
// rethrow the exception that was
// active when doSomethingElse was called
throw;
}
catch (...)
{
throw; // and let it go again
}

throw "this replaces the old exception";
// this new one takes over, begins stack unwinding
// leaves the catch's scope, old exception is done living,
// and now back to normal exception stuff
}

try
{
throw "original exception";
}
catch (...)
{
doSomethingElse();
throw; // this won't actually be reached,
// the new exception has begun propagating
}

Of course if nothing throws, throw; will be reached and you'll throw your caught exception as expected.

Will C++ throw with no arguments work inside another frame to rethrow an exception?

The wording in the standard (§15.1/2) is (emphasis mine):

When an exception is thrown, control is transferred to the nearest handler with a matching type (15.3); “nearest” means the handler for which the compound-statement, ctor-initializer, or function-body following the try keyword was most recently entered by the thread of control and not yet exited.

When has a try block "exited"? According to the grammar (§15/1), try blocks end with a sequence of handlers, so the block ends when the last handler ends. In other words:

try // <- start of try block
{
}
catch (whatever) // <- first handler
{
}
// ... more handlers
catch (whatever_again) // <- last handler
{
} // <- end of try block

So yes, your code is fine. When re-thrown, the nearest try block has a matching handler (namely catch (...)), so that handler is entered.

Is re-throwing an exception legal in a nested 'try'?

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:

§15.1/4:
The memory for the temporary copy of the exception being thrown is allocated in an unspecified way, except as noted in 3.7.4.1. The temporary persists as long as there is a handler being executed for that exception.

That is:

catch(...)
{ // <--

/* ... */

} // <--

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 dispatch without an active exception, terminate will be called. If dispatch throws an exception in one if it's handlers, that exception will begin to propagate. More information in a related question.

What happens if I use throw; without an exception to throw?

If handle() is called outside the context of an exception, you will throw without an exception being handled. In this case, the standard (see section 15.5.1) specifies that

If no exception is presently being handled, executing a throw-expression with no operand calls terminate().

so your application will terminate. That's probably not what you want here.

Rethrowing exceptions in Java without losing the stack trace

catch (WhateverException e) {
throw e;
}

will simply rethrow the exception you've caught (obviously the surrounding method has to permit this via its signature etc.). The exception will maintain the original stack trace.

ellipsis try catch on c++

No, it'll only catch C++ exceptions, not things like a segfault, SIGINT etc.

You need to read up about and understand the difference between C++ exceptions and for want of a better word, "C-style" signals (such as SIGINT).

cpp: catch exception with ellipsis and see the information

Sorry, you can't do that. You can only access the exception object in a catch block for a specific exception type.



Related Topics



Leave a reply



Submit