Invariant and pre/post-conditions order

Steven Schveighoffer schveiguy at yahoo.com
Fri Jan 20 09:05:25 PST 2012


On Fri, 20 Jan 2012 00:01:40 -0500, Walter Bright  
<newshound2 at digitalmars.com> wrote:

> On 1/19/2012 8:19 PM, Steven Schveighoffer wrote:
>> If they are related, yes it does give you more information. The out  
>> condition
>> might not check the class data directly, but the error which caused the
>> invariant to fail could have also caused the out-condition to fail. It's
>> inconsequential to the *program* whether the out condition or the  
>> invariant
>> halts execution. But to the developer receiving the assert message,  
>> it's much
>> more helpful to see an out condition failing than an invariant. If they  
>> are
>> related, and caused by the same bug, it's that much more helpful.
>
> I utterly fail to understand your argument about it being more helpful.

For a class with 50 methods:

invariant error -> one of your 50 methods may have messed up the  
invariant, but I'm not going to tell you which one.  Also, it could have  
been messed up somewhere else, and failed at the beginning of a method  
call, or an extraneous assert.  Have fun looking for where the bug is.
out condition error -> method 25 failed condition at line X.

>> Imagine you
>> have 1000 lines of code that call 50 or so different methods on a  
>> class. Any one
>> of those calls in any one of those methods could cause an invariant  
>> failure. But
>> only one method call can cause a specific out condition failure, and  
>> the lines
>> of code that call that function might be significantly less than 1000  
>> (maybe a
>> handful).
>
> This does not make sense to me. If a bug would cause an invariant  
> failure and an out failure, and one is run right after the other, there  
> is zero advantage to one being run before the other.
>
>     assert(s);
>     assert(s);
>
> which one should be run first?

They are not *located* one right after another.  One is in the invariant  
function which could be called from anywhere, and one is directly attached  
to the code which caused the bug.  Asserts are not only helpful by telling  
you that they failed, but also *where* they failed.  It's not always  
guaranteed that you get a useful stack trace to see where the program is  
running, but you do always get an assert message.

>
>> With almost no change to execution speed, semantics, or pretty much  
>> anything,
>> you will have saved the developer minutes to hours (under the right
>> circumstances, maybe even days or weeks) of crappy "how the hell do I  
>> find this
>> bug" time.
>
> I see no advantage, even to your hypothetical. I think you would be  
> *very* hard pressed to come up with an example.

I've had programs that I have written which failed once every 2 weeks.

If such a situation happens, and you just get a single-line assert  
message, then you have to instrument, or run in debugger, wait another 2  
weeks.  Or maybe you get a stack trace without any readable.  Not as bad  
as waiting two weeks, but if you can tell me more information about where  
the program is without me having to get out my stack decoder ring, DO IT!

My philosophy to error reporting is, give me as much information as  
possible about the current state of the program.  Especially for errors  
which are about to make all the evidence go away (aborting errors).  It's  
not perfection, it's not even guaranteed, but do whatever is possible to  
make things easier to figure out without complex tools.

This is a small change for a small gain, but it's a very very simple  
change.  You just reorder one generated call.  The cost is probably less  
than the effort we have expended discussing this.

>> even your second reason is flawed -- in order for there to be a  
>> noticeable
>> difference, one would have to make their invariant actually *change*  
>> the object.
>> Why do we support that? In fact, this change would help them discover  
>> their
>> flawed invariant code :)
>
> Invariants and conditions are allowed to be impure so they can do things  
> like logging.

How does this destroy prior work?  Log messages are slightly out of  
order?  Still not buying it.

-Steve


More information about the Digitalmars-d mailing list