assert(obj) is an atrocity

Jonathan M Davis jmdavisProg at gmx.com
Sun Nov 13 13:38:25 PST 2011


On Sunday, November 13, 2011 18:52:35 Alex Rønne Petersen wrote:
> I'd just like to add, regarding asserting invariants: Why not just *make
> invariants callable*? I.e. obj.invariant() invokes the invariant
> function. invariant is already a keyword, and invariants are declared
> like functions, so this seems like a logical thing to do.

Call __invariant. But like all __ functions, I don't think that it's really 
intended to be called directly in code. You can do it though.

Really, I don't think that there's a problem with assert(obj) calling obj's 
invariant. It's just extra overhead in a non-release build which is running a 
set of assertions which should be true anyway (assuming that it's being called 
outside of the class). It's the fact that it doesn't check for null first which 
is so atrocious, since that _completely_ changes the semantics of what obj 
normally does when implicitly converted to bool. If it checked for null first, 
then the normal semantics hold with the addition of checking the invariant.

The fun part about assert(obj) though is that it doesn't work with structs - 
not directly anyway. If obj is a struct, assert(obj) tries to convert it to 
bool like it would do normally. However, assert(&obj) _does_ call the 
invariant. Pointers to structs are treated exactly the same as references to 
classes in this case (complete with the lack of a null check). So, it's 
arguably consistent, but it's a bit weird.

In any case, what really needs to be done is to add the extra null check. It 
won't silently break code to do that, and it'll avoid the surprise and 
confusiong of assert(obj) not checking for null and blowing up as a result.

- Jonathan M Davis


More information about the Digitalmars-d mailing list