Hi,
(sigh) Another *@&^#($ night of "tree sitting". This gets old REALLY FAST! :-/
Anyway, between trips outside, I've been dressing up some old bits of software -- cleaning up commentary, etc.
One of the things I do to help with debugging as well as making interfaces more explicit is to place DEBUG-only invariants at the start of each function that "verify" the terms of the invocation contract. E.g., if a pointer can't be NULL, I'll do something like:
ASSERT( (src != NULL), "Pointer to source must be non-NULL" );
At run time, these go away (usually... depends on the market I am serving). So, they don't "cost anything". And, they make the interface rules *very* explicit (while the commentary could possibly be ambiguous, the conditionals in the invariants are hard to argue with!).
So, the start of each function is usually a list of several ASSERT()'s -- at least one for each parameter (usually). Then, the meat of the function begins.
One of the routines I was dressing up today had some constraints placed on a pointer passed to it. In particular, requiring the pointer to reference a valid memory location in a certain range (defined by manifest constants).
ONCE THROUGH THE INVARIANTS, "live code" would further qualify the parameters passed to the routine. In this case, enforcing some "arbitrary" alignment criteria. Conceivably, the aligned pointer could now reference something *outside* the range of memory locations enforced by the invariants. The code clearly has to test for this -- since the whole point is to ensure those "out of bounds" areas are not referenced at run-time.
Now, the nit pick... *technically*, the caller has complied with the contractual requirements of the function (the contract doesn't enforce alignment issues -- that is part of the role of the function itself). As such, I maintain that the original set of invariants are *all* that should be enforced (to determine if the invocation "complies"). The *further*, non-contractual alignment restriction that the function imposes should be treated as a run-time error -- just like trying to resolve "ptr[index]" when the location referenced extends outside of the valid range.
In other words, I should *not* include a second set of ASSERT's to examine the "aligned" parameters after their initial validation.
Agreed? Else, where does it end?? (it is really "clean" having the invariants clumped in one cohesive group)
Thx,
--don