A better assert() [was: Re: std.unittests [updated] for review]
bearophile
bearophileHUGS at lycos.com
Sat Feb 5 06:39:01 PST 2011
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 at 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
More information about the Digitalmars-d
mailing list