Wonderful articles have been published recently, I would like to add a few more paragraphs on this topic.
Dear authors of previous topics somehow missed that moment (or did it seem to me? Or is this self-implied?) That exceptions arose as a tool for solving a very utilitarian task -
transfer of control from the place of occurrence of the error to the place where it
can be processed .
A bit of history to make it clear where this problem came from. In each more or less non-trivial software (harder than “Hello, world”, yes), there are always points where normal execution cannot continue - the I / O subsystem failed, the algorithm did not have enough memory for the algorithm, input parameters for she did not like the functions, etc. How exactly to respond?
')
The situation becomes even sadder if we consider the creation of a library that should be used in other projects. We cannot (as a result) call assert / abort or some other similar handler - how do we know that we have the right to shut down the entire application? For example, our library is engaged in collecting some statistics of input data, and because of this behavior, the entire device will be stopped. And we write the firmware for the pacemaker, of course.
Ok, abort () is no good. We do not want to create applications like a balloon — it pricked anywhere, the whole ball died. We want to use technology that will allow us to divide the place where the error occurred, and the place where the decision is made about what exactly we will do with this error. Since for some applications the reaction will be to prohibit the collection of these statistics, for others - the library will be re-initialized (for example, with other parameters), somewhere - just ignoring.
Since at a higher level, much more information is available on how to respond to an error.How else can we signal “up” about our problems? Global variables of type errno in the C language? Will not work. Return value? Already better, but new problems arise:
- the programmer now has a burden of responsibility for checking the return value each time such functions are called,
- the whole program at all levels must now support this approach (for the situation when a function was called from our library, it returned an error, the caller found it and returned the error itself, and at a higher level it was missed - let's say, undesirable)
- The chain of calls consists of very similar blocks: they called the function, checked for the presence of an error, if it exists, we exit ourselves with an erroneous sign. And if it is necessary to write it all the time - why is it not automated?
Actually, here was made another logical step. The language has a tool that allows you to:
- to divide the place of error detection and the place of reaction to it,
- does not impose on the programmer the duty to check every call of each function, so as not to lose an accidental error,
- if the error is not processed at the current level - do not worry, it will take more upper. Perhaps he will already know what to do with her
- supported by the language itself - we do not need to modify the existing code in order to teach it to send an error upward in this new way.
This tool is exceptions. It is naturally obtained as the result of introducing into the language the concept of error handling that was described above. This tool has its advantages and disadvantages (which sometimes make them completely stop using them). Moreover, “handling error situations” is a general concept, and “handling error situations using exceptions” is just one example of its implementation. Error handling can be done without using the exceptions mechanism, unless action from the programmer is somewhat more required.
Actually, it was all written in order that a better understanding of “what exactly” serve the exceptions would allow us to better understand “how to apply them and for what cases”.
PS: there was also a desire to show with examples of the code exactly what cons of exceptions. And how the problem was solved “it is convenient to handle errors and not to use exceptions” (relevant for embedded systems when “pacemakers” are written). But that later.