In general, where does program execution resume after an exception has been thrown and caught? Does it resume following the line of code where the exception was thrown, or does it resume following where it's caught? Also, is this behavior consistent across most programming languages?
It resumes where the exception is caught. Otherwise, what would be the point of writing the exception clause?
The code inside the catch block is executed and the original execution continues right after the catch block.
Execution continues in the catch block (where the exception was caught).
This is consistent across languages that uses exceptions.
The important point to note (especially in C++)
Between the throw and the catch point the stack is unwound in an orderly manor so that all objects created on the stack are correctly destroyed (in the expected order). This has resulted in the technique knows as RAII.
the execution resumes where the exception is caught, that is at the beginning of the catch
block which specifically address the current exception type. the catch block is executed, the other catch blocks are ignored (think of multiple catch
block as a switch statement). in some languages, a finally
block may also be executed after the catch
. then the program proceed with the next instruction following the whole try ... catch ... finally ...
.
you should note that if an exception is not caught in a block, the exception is propagated to the caller of the current function, and up the call stack until a catch
processes the exception. in this case, you can think of function calls like a macro: insert the code of each function where it is called, and you will clearly see the nesting of every try .. catch ... finally ...
blocks.
if there is no handler for an exception, the program generally crashes. (some languages may be different on this point).
the behavior for the execution flow is consistent accross every languages i know. the only difference lies in the try ... catch ... finally ...
construct: the finally
does not exists in every language, some languages does not allow a finally
and a catch
in the same block (you have to nest two try
to use the 2), some languages allows to catch everything (the catch (...)
in C++) while some languages don't.
I don't have my copy of Bjarne Stroustrup's "Design & Evolution" handy, but I believe he wrote in there about some experience with resumable exceptions. They found that they made things considerably harder to get correct. After all, if an unexpected error happens in some line, your exception handler then has to patch the problem up sufficiently to allow execution to resume without knowing the context. This may be possible for an out-of-memory error (although such errors are frequently a result of runaway memory allocation, and adding some more memory won't really fix anything), but not for exceptions in general.
So, in C++ and all languages I'm familiar with, execution resumes with the catch, and doesn't automatically go back to the place that threw the exception.