info-sather
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exceptions


From: Norbert Nemec
Subject: Re: Exceptions
Date: Mon, 2 Oct 2000 08:45:04 +0200
User-agent: Mutt/1.0.1i

On Sun, Oct 01, 2000 at 06:30:51PM -0700, Quinn Dunkan wrote:
>
> > After all: Exceptions are the method of choice wherever there are 
> > errors that occur at runtime that can't possibly caught by the compiler 
> > (IO-Errors etc) For everything else, there should theoretically be a 
> > compile-time check. Anyhow, theory does not help much here, since many 
> > things just cant be checked at compile time. Still pre/post-conditions 
> > and assertions are a better solution here.
> 
> This actually raises (aargh!! *blam*) a question I have about DBC.  Supposing 
> I
> have:
> 
> class FILE is
>     read(nchars:INT) pre is_open is
>         ...
>     end;
>     is_open:BOOL is
>         ...
>     end;
>     open(fname:STR) pre PATH::file_exists(fname) is
>         ...
>     end;
> end;
> 
> Is the precondition on 'read' right or wrong?  It looks right because only a
> buggy program would read after a close.  But the precondition on 'open' is
> almost certainly wrong, because one frequently opens a file based on
> user-input, so a perfectly ok program will often attempt to open a
> non-existent file.  If the precondition is there, it will kill your whole
> program.

That's exactly how I see it: the first pre is correct, since in a 
correct program, if the open did not raise an exception, the file 
definitely is open. Of course, the read can still fail for some reason 
and raise some IO-exception, but that's another matter.

The second open is completely wrong, since you can't do a reliable check for 
file_exists outside open. Even if the check said that the file exists, 
it might still be deleted in the microseconds between the two calls.

> The only way around would be to catch the AssertionError exception
> (if it is one), but once you can catch assertion failures at run time you're
> replacing compiler-provided safety features with your own hand-coded runtime
> "safety features" which is wrong.

Why no have that AssertionException? As default, the running program 
can only abort - which is hardly a "compiler-provided safety feature". 
If preconditions were checkable at compile time, you'd be right, but 
that would mean complete data-flow analysis. Why not catch a bug in the 
program in a nicer way to the user? Perhaps print our a huge SORRY... 
:-)

> In the case of 'read' and 'open' the distinction is clear.  But the criterion
> for the distinction: whether the precondition could *only* be violated by a
> buggy program and not by user input, is not well-defined.  This means there is
> *another* contract between the library and the program about what the program
> is allowed to pass from the user directly to the library, and everything else
> must be a bug in the program.  Is that "meta-contract" well-defined?  What
> about a "meta-meta-contract"?  I'd say this means there is no way to know for
> absolutely sure whether you should precondition something or not, but since
> the effects of a bad precondition choice are unpleasant (forces you to
> duplicate the precondition in your own code at runtime to avoid blowing the
> whole program up), you shouldn't use them unless you're really sure.

Usually, you should never need those precondition-checks outside the 
functions. Of course, you have to check any kind of input for 
correctness, but once the data is within your program, you have 
complete control over it.

Of course, it might help to put pre/post-conditions to your own 
routines as well, but still that's only to help catching possible bugs.

In a library it should be hard to make over-use of pro/post-conditions. 
As long, as you don't prevent the user from doing things that would be 
legal by the contract, everything is fine.

The distinction an named before *is* clear: The pre-/post-conditions 
themselves represent (part of) the contract. They can only hit, if a 
user (app-developer) ignores the contract in some way. However he makes 
sure to avoid that is left to him (asserts may help, but the only 
correct way is "hand-made data-flow analysis" - i.e. tracking where the 
values came from and checking where a faulty value might creep in 
before the library call.

> But if you tend to not use them, isn't that defeating their purpose?  I guess
> the answer is that the code duplication is desirable, because while both
> pieces of code are performing the same check, they're doing on different
> conceptual levels.  So presumably precondition-check methods shouldn't be
> private because the user will want to call them himself at runtime.

You are not duplicating anything: In a correct program, only the input 
has to be checked, and that can never be avoided.

> So exceptions can indicate an exceptional occurrance, an error, or a bug.
> Assertions can only indicate a bug.

Actually, exceptions should not even be used for catching bugs. Of 
course, a bug may an exception to be raised somewhere, but an exception 
of the kind "internal error at position..." should never be raised 
anywhere.

> I guess I should really read what Meyer says about this stuff.

Be aware, that he was one of the first to proclaim design by contract 
at all. I do not beieve that Eiffel does cover that topic perfectly 
(neither does Sather of course) - so i do not know how completely he 
covers the theory behind it in his books.

Ciao,
Nobbi

-- 
-- ______________________________________________________
-- JESUS CHRIST IS LORD!
--          To Him, even that machine here has to obey...
--
-- _________________________________Norbert "Nobbi" Nemec
-- Hindenburgstr. 44  ...  D-91054 Erlangen  ...  Germany
-- eMail: <address@hidden>   Tel: +49-(0)-9131-204180



reply via email to

[Prev in Thread] Current Thread [Next in Thread]