From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,2e71cf22768a124d X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: Assertions (an heretic view) Date: 1996/06/28 Message-ID: #1/1 X-Deja-AN: 162569082 references: <4ql1fv$5ss@goanna.cs.rmit.EDU.AU> organization: The World Public Access UNIX, Brookline, MA newsgroups: comp.lang.ada Date: 1996-06-28T00:00:00+00:00 List-Id: In article , Michel Gauthier wrote: >IMHO, it is _essential_ to distinguish : > - _failures_ : some piece of program does not do what it has been designed > to do, in an intrinsicly impossible case, > - _programming errors_ : the programmer did not do what the specification > required, including failure cases. A perfectly reasonable distinction. However, you cannot, in general, tell whether it's a "failure" or a "programming error" at the point where the problem is detected. This is the whole point of exceptions: one piece of code can detect the problem, and another piece of code, possibly far away, can decide whether it is a "failure" or not, and if so, what to do about it. (And, of course, the *usual* thing to do with an exception is to treat it as a programming error, and simply let it kill the program or go into the debugger or whatever.) >Underflowing a stack is (almost always) an error, whereas overflowing a >stack depends on the data and on the environment of each execution, hence >is a failure. > >Failures can _always_ be foreseen, and suitable programming can handle >them if appropriate, with exceptions or with any other means. > >Errors can _never_ be foreseen. > >Coming back to assertions, I guess that they essentially relate to errors, >which they can help detecting. It seems to be a good style not to combine >assertions with failures. I disagree, for the above reasons. If you have a stack overflow, it might be a "failure", and it might make sense to recover from it. On the other hand, I might calculate the maximum stack size, so that my algorithm is guaranteed not to overflow the stack -- in this case, the only way the stack can overflow is if I have a programming error. And the code for Stacks.Push can't tell which is which. Only the *caller* of Stacks.Push can know. >Moreover, I can't agree with the idea that failing an assertion check would >always result in raising Assert_Error. Failing an assertion check is an effect >of some -possibly incompletely identified- programming error. Different >possible continuations can be envisaged : raising a well-specified >exception associated with the case, doing some appropriate thing >(tracing,...), raising some user-defined exception, invoking the debugger, >and possibly others, among which continuing until other failing checks. > This choice depends on the current status of the project, on the >nature of the checked assertion, on reuse or not, etc. In some cases, >it may depend also on execution options. Right. But "raising an exception" covers all these cases. Any decent implementation will let you go into the debugger in case of an unhandled exception, for example. Anyway, you have no choice -- the language Standard doesn't define an Enter_Debugger primitive. - Bob