I'm confused, too. Exceptions can be thrown everywhere, is that right? But
what is the purpose of the try block? Why isn't it enough to write a catch
block if the exceptions can be thrown in the try block and outside the try
block? (I know it's not valid to write catch without try, it's just to
understand how things work.)
Contrary to the other posters in this thread, C++ exceptions cannot be
thrown from anywhere.
In short, a C++ exception can only result from an executed "throw"
statement or or a failed dynamic_cast<reference_type>. (IIRC, those
are the only two things.)
C++ exceptions can also be thrown from standard library functions and
classes, such as std::vector, and from language features, such as the
new operator. However, these are likely implemented using "throw"
statements, and that's the better way to think about it. (Yes yes. I
know they don't have to be. Standard library functions and features
can be implemented whatever silly way they want. That's why I
specifically called them out.)
In practice, because of the widespread use of such features, it's
almost as if exceptions can come from anywhere, but C++ exceptions are
synchronous - they only come from a very specific set of things which
can throw.
If you want to talk about asynchronous exceptions, or exceptions from
null pointer accesses (such as what Visual Studios did by default in
older versions), then you're no longer talking about standard C++, and
you ought to consult those newsgroups and those documents instead.
Now, on to your question. Consider the code:
#include <iostream>
using namespace std;
int main()
{ try
{ try
{ throw 1;
}catch (... )
{ cout << 2 << endl;
throw 3;
}
}catch (... )
{ cout << 4 << endl;
}
throw 5;
}
Every catch block has exactly one associated try block. The reason is
that the catch block will only be invoked on exceptions thrown from
within that try block. For example, in the above code, throw 1 will
throw an exception from within a try block. That try block has an
associated catch block which matches the thrown exception (... matches
all exceptions), so that catch block will be executed. 2 is printed.
That catch block during execution executes another throw statement,
throw 3, which will throw a new exception. That new exception is
inside a different try block with an associated matching catch block,
so that associated catch block will be executed. 4 is printed.
Finally, control flows past the end of that catch block, and it hits
the throw 5 statement. This throw is outside of any try block, so it
is not caught, and so the program dies.