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 callsterminate()
.
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
Parameter Name Omitted, C++ VS C
Strange Ambiguous Call to Overloaded Function Error
When Is Explicit Move Needed for a Return Statement
Gcc -Wuninitialized/-Wmaybe-Uninitialized Issues
Cost of Throwing C++0X Exceptions
Why Does Constexpr Static Member (Of Type Class) Require a Definition
Right Shift and Signed Integer
Does C and C++ Guarantee the Ascii of [A-F] and [A-F] Characters
How Does the Linker Handle Identical Template Instantiations Across Translation Units
Why Is Operator!= Removed in C++20 for Many Standard Library Types
Cannot Create Constexpr Std::Vector
Why Sizeof Built in Types Except Char Is Compiler Dependent in C & C++
Calculating and Printing Factorial at Compile Time in C++
Why Was Pair Range Access Removed from C++11