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