Suggestion: "fix" assert(obj)

Georg Wrede georg at nospam.org
Fri Jun 15 18:49:05 PDT 2007


((Reversing another top-post))

Ary Manzana wrote:
> Kristian Kilpi escribió:
> 
>> This issue has been proposed before. Well, I think it's the time 
>> suggest it again...
>> 
>> The problem is that
>> 
>> assert(obj);
>> 
>> does not first check if 'obj' is null. It just executes the
>> object's invariants.

> Why would you want to check an object's invariant? Isn't the compiler
> doing that before and after you execute a public method? What's the
> use for it?

First: checking invariants is (most normally) a runtime excercise. 
Normally the situations that lead to a risk of "breaking" the invariants 
are due to circumstances the programmer didn't think of at first hand, 
which naturally suggest a runtime check, usually with Real Use Case Data.


(
Ahh, not for Ary, but for general explaining: object (or more to the 
point, instance) invariants are not variables that stay the same. Not 
even variables that stay the same before and after method calls. Rather, 
they are _logical_ properties of the instance that the instance should 
want to maintain, even if not explicitly mentioned in the algorithms or 
source code.

An example:

   We have a class that tracks hours and minutes charged from
   customers.
   Hours worked are added, but for convenience, you can add
   the whole day and then subtract coffee breaks and lunches.
   The invariant for the class HoursWorked would then be

   !(minutes < 0 && minutes => 60)

The invariant is kind of a consistency check between the values of the 
instance variables. So, an invariant is any function (of one or more of 
the variables of the instance) that has to resolve to True _whenever_ 
evaluated between method calls. E.g., a class of carpet sizes would have 
width and length and area, and the invariant would be 
width*length==area, and possibly also (width>=0 && length>=0).
)


Second: invariant checking should be run both before and after any 
method is run, which makes it a property of non-release code.

For that purpose, the invariant section exists in D. (Or will be.)

---

Now, having assert(o) check for the invariants makes for sloppy coding. 
If the coder is lazy enough to not want to write

   assert(myFancyObject.checkInvariants())

and wants to instead only write

   assert(myFancyObject)

then it should be expected he'd be stupid enough to make un-called-for 
shortcuts elsewhere too.


At the same time the rest of us have (as it seems) learned to never write

   if (o) {act;}

and instead write

   if (o !is null) {act;}

which not only does contain a double negation, it also is unnecessarily 
verbose and prone to logical errors. Not to mention, it violates C 
family heritage -- thanks to a trivial detail, not even related to the 
issue at hand!



More information about the Digitalmars-d mailing list