Why does `catch` catch the throw here? - c++

I'm not really sure what's happening here. Its obvious why the inner catch catches throw 2, but why does the outher catch(int x) catch throw? I thought catch(int x) is supposed to catch integer values only. Is it possible that the second throw throws what was first cought (which is 2)?
try
{
try
{
throw 2;
}
catch (int n)
{
std::cout << "Inner Catch " << n << std::endl;
throw;
}
}
catch (int x)
{
std::cout << "Outer Catch " << x << std::endl;
}
Thanks!

You cannot throw nothing. throw; alone can be used in a catch-block to rethrow the currently handeled exception. From cppreference:
Rethrows the currently handled exception. Abandons the execution of
the current catch block and passes control to the next matching
exception handler (but not to another catch clause after the same try
block: its compound-statement is considered to have been 'exited'),
reusing the existing exception object: no new objects are made. This
form is only allowed when an exception is presently being handled (it
calls std::terminate if used otherwise). The catch clause associated
with a function-try-block must exit via rethrowing if used on a
constructor.
I thought catch(int x) is supposed to catch integer values only
Thats what it does.
Is it possible that the second throw throws what was first cought (which is 2)?
Exactly that.

Related

Difference between catch(exception &e) and "catch(...)? [duplicate]

I know the difference in handling of both of these catches, but what does it take for the ellipse to catch something the std::exception catch wouldn't catch?
For example:
try
{
throw std::runtime("runtime error!");
}
catch(const std::exception& e)
{
std::cout << "Exception: " << e;
}
catch(...)
{
std::cout << "How did I get here?";
throw;
}
I've seen examples of code that use both of these in conjunction, but I've not seen a reason you would do both.
catch(const std::exception& e)
Will catch std exceptions only.
catch(...)
Will catch everything there after.
You can handle integers and other types (http://www.cplusplus.com/doc/tutorial/exceptions/)
For example:
catch(int e)
While it's definitely a good idea to do so, you don't have to derive your custom exceptions from std::exception. C++ allows you to throw practically any object type.
So throw 1; will not be handled by your first handler, for example. And neither will...
class MyCustomException { // Doesn't derive
///
};
... if it was thrown.
You probably meant:
throw std::runtime_error("runtime error!"); // not std::runtime
The std::runtime_error is derived from the std::exception so your first catch block is fired up as it catches exceptions of type std::exception. And there you probably meant:
std::cout << "Exception: " << e.what(); // not e
If you threw anything else other than the std::run_time or std::exception and its derivatives, the second catch block would be triggered. Useful reading from the C++ FAQ:
What should I throw?
As written, the throw statement throws an object whose type is derived from std::exception, so it's caught by the first catch clause. If you change the throw to throw 3; the exception will be caught by the second catch clause, not the first.

Exception mechanism issue in c++

I am calling a function and I am throwing an exception in that function. But I don't want to catch that in the same function but want to catch it where that function was called, like here is my example code.
void foo()throw(...){
std::cout << "FOO" <<std::endl;
throw "Found";
}
void main(){
try{
foo();
}
catch(...){
std::cout << "exception catched" <<std::endl;
}
}
But it is crashing at the point where I am throwing the exception in foo function, but I want to catch it in the main function.
How would I do that?
throw;
throw with no operand rethrows the exception that is currently being handled. That means it can only be used in a catch block. Since you aren't in a catch block when the throw; is executed, the program is terminated.
You need to throw something, like a runtime error: throw std::runtime_error("oops");.
Note also that exception specifications (e.g. the throw(...) in void foo() throw(...)) should not be used. For an explanation as to why, see "A Pragmatic Look at Exception Specifications."
Got answer my own question at http://msdn.microsoft.com/en-US/library/wfa0edys%28v=VS.80%29.aspx

Nested try-catch blocks?

int main ()
{
try
{
try
{
throw 5;
}
catch (int n)
{
throw;
}
}
catch (...)
{
cout << "Exception occurred";
}
}
This prints out "Exception occured" but
int main ()
{
try
{
try
{
throw;
}
catch (...)
{
throw;
}
}
catch (...)
{
cout << "Exception occurred";
}
}
This just errors. It seems like I'm doing the try-catch's exactly the same! The only difference is that in the first case I'm throwing an int, then a general exception, but in the second case, I'm throwing a general exception both times. Is the program confused as to which catch to go to?
There's no such thing as "general exception" and you throw no such thing.
In the first example, you throw an int, then you re-throw the exception that you are handling. That's the meaning of throw without an argument.
In the second example you start with an attempt to re-throw an exception that you are handling. As you are not handling an exception at that time, you get an error.
Your 2nd example terminates the program with a good error message (at least using g++ 4.6.1):
terminate called without an active exception
Aborted
This happens because you are trying to re-throw an exception, but since there are no active exception, the program terminates.
The current c++11 draft, in chapter 15.5.1 says this:
In some situations exception handling must be abandoned for less
subtle error handling techniques.
Then in the list of cases when std::terminate is called is this:
when a throw-expression with no operand attempts to rethrow an
exception and no exception is being handled (15.1),
So, the behavior from your 2nd example is well defined in the standard.

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.