Think, now: where would your good be if there were no evil, and what would the world look like without shadow? M. Bulgakov, The Master and MargaritaNormally a function operates on some domain of arguments, to produce a result in some range. If a programmer wants the function to be robust, which should always be the case, he should provide for the ways to handle arguments that the function cannot by definition act upon. For example, consider that you have to write a function
TRUE
on success of the operation
and FALSE
otherwise. But that requires having an extra variable, and is
not really convenient. Plus, neither of these two ways provide for a
really graceful method of handling errors -- the ability to either
handle error on the spot OR pass it "up" all the way through the callers
of the failed function. This can be done with exceptions.
In the case of our function (square root) the result of the execution of
the function can be either the calculation and return of square root of
x
, if x>=0
, or an exception can be raised by the function, signaling
that some kind of an error occured. The exception can then be caught by
the function that called sqrt and dealt with as the function wishes --
an error message can be printed, the exception can be ignored, or passed
on to the caller of the caller of sqrt
... isn't it beautiful?
Now if the words were a little confusing, let's look at how it's done in C++...
To use exceptions you must have a class defined for each exception. For
example, supposed you have a class for an out of range error called
OutOfRange. Now, in the body of your function you can check whether the
argument is >=0
(we are still using sqrt
as an example), and if so,
return the square root. Otherwise, we raise an exception, like this
To make the defensive programming even easier, the exceptions can have arguments, so you can deal with exceptions in the catch clause according to the arguments.
What about unhandled exceptions, the ones that are not caught? Well, the
terminate()
function is called, which executes the absolutely
last-resort handling function that can be specified with set_terminate
function, which takes a void function with no parameters. If no such
last-resort function was set, the terminate()
function by default calls
abort()
.
Well, that's all there is to know about exceptions. By the way, it's a very recent addition to the language, and very few compilers support it. For example, g++ that I use (2.6.0) does not, and GNU compilers support a lot of features...
<grisha@mit.edu>