Why Does C++ Have a New Error Mechanism?
C++ uses the exception mechanism for errors. What′s wrong with error returns like FORTRAN used to make? Factorials cannot be negative, so you could have said something like “Okay, if factorial() detects an error, it returns a negative number. The actual value indicates the source of the problem.” What′s wrong with that? That′s how it was done for ages. (“If it was good enough for grandpa…”)
Unfortunately, several problems arise. First, although it′s true that the result of a factorial can′t be negative, other functions aren′t so lucky. For example, you can′t take the log of a negative number either, but logarithms can be either negative or positive. There’s no value that a logarithm function can’t return.
Second, there′s just so much information that you can store in an integer. Maybe you can have –1 for “argument is negative” and –2 for “argument is too large.” But, if the argument is too large, you want to know what the argument is because that information might help you debug the problem. There′s no place to store that type of information.
Third, the processing of error returns is optional. Suppose someone writes factorial() so that it dutifully checks the argument and returns a negative number if the argument is out of range. If a function that calls factorial() doesn′t check the error return, returning an error value doesn′t do any good.
Sure, you can make all kinds of menacing threats, such as “You will check your error returns or else,” and the programmer may have the best of intentions, but you all know that people get lazy and return to their old, non-error-checking ways.
Even if you do check the error return from factorial() or any other function, what can the function do with the error? It can probably do nothing more than output an error message of its own and return another error indication to the caller, which probably does the same. Pretty soon, there’s more error detection code than “real” code and it’s all mixed together.
The exception mechanism addresses these problems by removing the error path from the normal code path. Furthermore, exceptions make error handling obligatory. If your function doesn′t handle the thrown exception, control passes up the chain of called functions until C++ finds a function to handle the error.
This also gives you the flexibility to ignore errors that you can′t do anything about anyway. Only the functions that can actually handle the problem need to catch the exception.