www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: A better assert() [was: Re: std.unittests [updated] for review]

reply bearophile <bearophileHUGS lycos.com> writes:
Adam D. Ruppe:

 LOL!

I like a bit of humour to keep myself serious/sane despite the strange discussions we have around here now and then :-)
 But, assert(0) does exactly what it says - assert this situation
 is invariably invalid.
 
 Something like class_instance.invariant() is better because:
 - It's explicit and readable.

So is assert(obj);

An assert(something) doesn't say in any explicit way that it will call the invariant, it's an information present only inside your head, that knows D mysteries. A syntax like class_name.invariant() or something similar is instead explicit in its purpose to call the invariant.
 This isn't really special. You're asserting the object is
 valid, which includes the invariant. If you want to only assert
 it is not null, you should write assert(obj !is null);

The semantics a not D-expert expects from assert(something) is to test that something is "true". For a class reference this means the pointer is not null. If you want assert() to do more for classes/structs/enums, then you are adding a special case to assert().
 Also, if you change to obj.invariant(), it will probably never
 be used. assert() is your one-stop shop for sanity tests.

:-)
 IMO that's the bug. It'd make a lot more sense to fix it so
 assert(struct) checks the invariant than to break assert(class)
 so it doesn't.

Removing a special case from assert() doesn't mean breaking it. One more "interesting" example: struct Foo { int x; invariant() { assert(x == 0); } T opCast(T:bool)() { return false; } } void main() { Foo f; assert(f); // line 8 } It generates: core.exception.AssertError test(8): Assertion failure Here the assert(f) is calling opCast, this according to DbC laws makes it call invariant first, here it passes, but then opCast returns a false, and the final assert fails. Bye, bearophile
Feb 05 2011
parent Adam D. Ruppe <destructionator gmail.com> writes:
bearophile:
 The semantics a not D-expert expects from assert(something) is to
 test that something is "true". For a class reference this means the
 pointer is not null.

This is the core of our disagreement: I think an object is not "true" if it's invariant fails. It means the object is completely invalid, no different than if it was a null pointer. It's unusable. The sooner this check is done, the better, so we can figure out where it went wrong.
 One more "interesting" example:

That makes sense, it's still analogous to if() like you'd expect. Actually, I wonder if doing if(obj) should check it's invariant too with classes, both for consistency with assert and getting that check done even more often.
Feb 05 2011