Why do we need exceptions checks like std::logic_error , if such errors are absent in the final program, i.e. extra checks done?

    2 answers 2

    Good question ... From a pedantic point of view, the program really should not contain logical errors. However, it is clear that in real life logical errors may well arise. They can be conditionally / informally divided into two groups: “unpredictable” errors, the occurrence of which the program did not predict (in response to which the program will either fall or continue to work in some semi-destroyed state), and “predictable” errors, when in a certain obviously present branch of a certain if appears in the user code, the control in which should never "/" cannot "fall". But what happens?

    This question has something in common with another question: should assert calls only exist in the debugging code, or should they be saved in the release version of the code? The truth, as a rule, is somewhere in the middle: the majority of assert in the code (in my, at least) are completely redundant and overly paranoid "sanity checks", which have no place in the release code, but some of them ( mainly responsible for the verification of contracts for the input data of the function) deserve to exist in the release version.

    And then the question arises: what to do when all the same such "impossible" branch of the code works? This is where the processing of the "logical error" level is appropriate. This may be the immediate completion of the program with the issuance of a diagnostic message. And maybe something more advanced, such as throwing an exception of the class logic_error . An exception can be thrown out both with the purpose of “tracking” the call stack that led to the error, and in order to carefully handle the situation, “swallow” the exception and still continue the program. It all depends on the specifics of the application.

      Although the description of the exception class suggests that such errors can most likely be identified before the program is executed:

      These errors are presumably detectable before the program executes.

      reference to derived classes:

      • domain_error (violation of the range of valid values)
      • invalid_argument (invalid argument)
      • length_error (exceeding the maximum length)
      • out_of_range (accessing an element out of range)
      • future_error (asynchronous call errors)

      may shed some light on the need to check for this type of error.

      As the amount of code increases, its complexity increases, the more complex the program, the greater the likelihood of an error in it (other things being equal). The desire to make the program "unkillable", i.e. so that even in the case of logical (algorithmic) errors, the program could terminate at least correctly (and not be nailed down by the OS), and as a maximum - even return to normal execution - leads to the need to weigh each potentially bad code section with additional checks. These are checks from the category of "what if I was wrong?", In fact, some kind of safety mechanism.

      Having caught a similar error once - in a good way, it is required to make changes to the code so that a second time the same chain of actions no longer brings the program to this state.

      An ideal program of this kind should not contain errors, but it may well lead to errors due to the non-ideal performance conditions, for example, equipment failure.