What does it mean to "throw" an empty expression? [duplicate] - c++

This question already has answers here:
What is the difference between throw and throw with arg of caught exception?
(2 answers)
Closed 9 years ago.
Sometimes in code I see throwing exceptions where the throw keyword is used without an expression next to it:
throw;
What does it mean and when should I use it?

An empty throw rethrows the exception.
It can appear only in a catch or in a function called from a catch.
If an empty throw is encountered when a handler is not active, terminate will be called.

It rethrows the exception of the currently active catch block.
try {
foo();
} catch (...) {
fix_some_local_thing();
throw; // keep searching for an error handler
}
If there is no currently active catch block, it will call std::terminate.

In a function declaration, it means that the function won't throw any exception.
In a catch block, it re-throws the caught exception, e.g.
try {
throw "exception";
catch ( ... ) {
std::cout << "caught exception";
throw; // Will rethrow the const char* exception
}

It's a rethrow of the current exception.
This doesn't alter the current exception, effectively just resuming the stack-unwinding after doing the actions in your catch{} block.
Quoting the standard: § 15.1 ad 8 [except.throw]
A throw-expression with no operand rethrows the currently handled exception (15.3). The exception is reactivated with the existing temporary; no new temporary exception object is created. The exception is no longer considered to be caught; therefore, the value of std::uncaught_exception() will again be true.
Example: code that must be executed because of an exception yet cannot completely handle the exception can be written like this:
try {
// ...
} catch (...) { // catch all exceptions
// respond (partially) to exception
throw; // pass the exception to some
// other handler
}

It's used inside a catch block to rethrow the current exception.

Related

Level of exception handling / rethrowing an exception

I have a function that basically returns an element from a vector using at(size_type pos). at() throws an std::out_of_range exception in case of an invalid (out_of_range) position.
I basically want this exception to be propagated to the caller, so that it can be handled on that level. Would the rethrow that I've added to my getter be necessary? Or would I get the same effect by just omitting the try-catch altogether?
int MyClass::GetNumber(size_t a_Idx) const
{
// Is the following try-catch-rethrow necessary? Or can the whole try-catch be omitted?
try
{
return m_Numbers.at(a_Idx);
}
catch (const std::out_of_range&)
{
// A throw expression that has no operand re-throws the exception currently being handled
throw;
}
}
MyClass m;
try
{
int t = m.GetNumber(42);
}
catch(const std::out_of_range&){}
I tried both, and didn't notice any difference, but I wonder whether I'm lucky, or whether this is guaranteed.
The exception thrown by std::vector::at(), as any other exception (someone correct me if I'm wrong), will unwind the stack until it reaches a try-catch block where it is caught, or cause an unhandled exception error if it isn't caught at any level.
Therefore, if your only intent is to catch it at the caller level, without any intermediate exception handling, there is no need to catch it in place and rethrow it: it will reach the caller's try-catch block, provided no intermediate try-catch block handles it.
It's guaranteed.
Exceptions bubble up until something catches them… unless nothing catches them, then your program aborts instead.
So, you do not need to explicitly re-throw through each scope.
Re-throwing would be useful if you had some extra work to do in that catch block before proceeding to let the exception bubble up as it was going to anyway.
Don't forget to note in your documentation that GetNumber(size_t) can throw std::out_of_range.

Will throwing an exception in a catch block lead to two exceptions being in flight? [duplicate]

This question already has answers here:
Nested try...catch inside C++ exception handler?
(2 answers)
Closed 1 year ago.
Consider the following C++ code:
class MyException {};
void someFunction()
{
try
{
/// ... code that may throw
}
catch(std::exception& e )
{
throw MyException();
}
}
Question
Is the exception e absorbed at the beginnging of the catch block or at the end of the catch block?
In the second case throwing the new exception would result in having two exceptions in flight, what is not what I want. I want to absorb the std::exception and start one of my own type.
No. That's how one should do it. The throw myException() can only occur if the first exception has been caught and hence is no longer 'in flight'.
This design pattern is quite common to 'translate' error messages coming from another library that your code is using to an error that the user of your code can better relate to.
Alternatively, if you want to do more than merely throw (say you want to do some clearing up of resources -- though that should really be done via RAII, i.e. from destructors), then you can simply rethrow the original exception via
try
{
// ... code that may throw
}
catch(...) // catches anything
{
// ... code that runs before rethrowing
throw; // rethrows the original catch
}
just throw; statement is enough in catch block to rethrow same exception in higher context.
It throws SAME exception again. No new exception is generated. So no fight :)
In case you want to catch exception of type A and then throw exception of type B, then the way you did it is absolute correct.
In this case, old exception (type A) is caught(absorbed) and only new exception(type B) is thrown to higher context. So, again no fight :)

Is it safe to throw / catch on stack unwind?

Q: Is it safe to throw and catch an exception on stack unwind, or does the application call terminate on the second throw?
minimal example:
void some_function()
{
try
{
// do stuff here that can throw
throw std::runtime_error("blah");
} catch(const std::exception& re)
{
try // this code could be in some function called from here
{
// do something with re here that throws a logical_error
throw std::logical_error("blah blah"); // does this call terminate?
} catch(const std::logical_error& le)
{
}
}
}
I got curious after reading this question.
Note: I know you can/should catch(...) in a destructor, but does it make sense in general to have a try/catch in a catch block - maybe in some function called on the exception (re in my example)?
That's not really during stack unwinding. Once a catch block is entered, the stack has already been unwound.
And yes, that code is legal. See this question: Nested try...catch inside C++ exception handler?
Pubby's answer best answers the scenario you're describing.
As an addendum, while a stack is unwinding, the only user code that's executed is destructors (and the code those destructors call).
If you do throw in a destructor during this scenario, the standard specifies that std::terminate() will be called.

Does catch (...) work on throw; with no object?

What does C++ standard say should happen for the following code when there is no pending exception being processed higher up the stack?
try {
throw;
} catch (...) {
cerr << "Caught exception." << endl;
}
Will the throw with no object be caught or not?
From the 2003 C++ Standard §15.1[except.throw]/8:
If no exception is presently being handled, executing a throw-expression with no operand calls terminate().
So, in your example, since no exception is currently being handled, nothing is thrown and instead terminate() is called. Since terminate() does not return, your catch block will never be entered.

What does a single "throw;" statement do?

These days, I have been reading a lot the C++ F.A.Q and especially this page.
Reading through the section I discovered a "technique" that the author calls "exception dispatcher" that allows someone to group all his exception handling in one handy function:
void handleException()
{
try {
throw; // ?!
}
catch (MyException& e) {
//...code to handle MyException...
}
catch (YourException& e) {
//...code to handle YourException...
}
}
void f()
{
try {
//...something that might throw...
}
catch (...) {
handleException();
}
}
What bothers me is the single throw; statement: if you consider the given example then sure, it is obvious what it does: it rethrows the exception first caught in f() and deals with it again.
But what if I call handleException() on its own, directly, without doing it from a catch() clause ? Is there any specified behavior ?
Additionally for bonus points, is there any other "weird" (probably not the good word) use of throw that you know of ?
Thank you.
If you do a throw; on its own, and there isn't a current exception for it to rethrow, then the program ends abruptly. (More specifically, terminate() is called.)
Note that throw; is the only safe way to re-throw the current exception - it's not equivalent to
catch (exception const & e) { throw e; }
Yes, it specified behavior, it will call terminate;
15.1, para 8: If no exception is presently being handled, executing a
throw expression with no operand calls
terminate() (15.5.1).
That's so-called exception handler. It rethrows the "current exception" if any. If there's no exception currently being handled terminate() will be called.