On Fri, 20 Jan 2012 00:01:40 -0500, Walter Bright <[email protected]> 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

Reply via email to