Topic: pre/post conditions, and pointer-testing (was F90 vs C++/C, optimization question?)


Author: martelli@cadlab.cadlab.it (Alex Martelli)
Date: 1995/10/26
Raw View
keagchon@mehta.anu.edu.au (Geoff Keating 9205156) writes:
 ...
>Hmmm. Suppose you claim that X[20][20] and Y[20] are not aliases of
>each other. What's wrong with:

>assert(&Y[20] <= &X[0][0] && X[20][20] >= Y[0]);

>(apart from the obvious fact that it's not portable)?

Well, another obvious fact is that you probably meant '||', not '&&':-).

Seriously, the problem with this is that it's not just "not portable",
it's *UNDEFINED BEHAVIOUR* to compare pointers that are not pointing
inside the same array -- a perfectly compliant compiler could make
demons fly out of your nose as a consequence of this code.

I fully agree with the spirit of your proposal -- we don't need more
special-cases, we need a more general solution that can solve several
problems at one stroke.  And that general solution, IMHO, hinges on
a way to attach assertions to classes and methods, exactly as it can
be done in Sather or Eiffel: class invariants, method preconditions,
method postconditions.  A debugging compiler can insert code to test
that (some or all) of the conditions are in fact met, an optimizing
one can accept that the assertions hold and perform all sort of
clever optimizations based on them, etc etc.

This specific problem highlights ANOTHER sore need: a *portable* way
to test for "is this pointer inside this array, or not".  Not only
would this be precious for pre/post/invariant assertions, it would
come in handy in all sorts of low-level programming situations --
a memory allocation subsystem could check to see whether it's
being passed a valid pointer for deallocation, for example (a more
general solution to this latter issue would probably also need a
portable way to test whether a given pointer is, or isn't, suitably
aligned for a given type).

bool isPointerInside(const void* pointerBeingTested,
       const void* startOfArray,
       size_t sizeOfArray);
ideally with startOfArray/sizeOfArray allowed to be, in fact, a
_sub_-array, e.g., give "double A[20];",

isPointerInside((const void*)&A[11],(const void*)&A[8], 5*sizeof(double))

would be valid (NOT undefined behaviour) and yield true,

isPointerInside((const void*)&A[14],(const void*)&A[8], 5*sizeof(double))

would be valid (NOT undefined behaviour) and yield false.


and maybe also:

template<class T> isPointerAligned(const void* pointerBeingTested);
(to be called as, e.g., isPointerAligned<double>((const void*)myptr))

would, I feel, be worthy additions, mostly for low-level programming.


Compiler-usable preconditions and postconditions, ones that can be
attached to methods (including pure virtual ones!) _in a class's
DECLARATION_, would be, IMHO, infinitely more precious still.  ("Class
invariants" can be seen as a special case of conditions applying as
both pre and post to all of the class's methods, so they're "merely" a
great notational convenience in this context).


Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it                            Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia   Fax: +39 (51) 597120

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: ebiederm@cse.unl.edu (Eric Biederman)
Date: 1995/10/27
Raw View
In article <martelli.814695566@cadlab> martelli@cadlab.cadlab.it (Alex Martelli
) writes:
    ...
   >Hmmm. Suppose you claim that X[20][20] and Y[20] are not aliases of
   >each other. What's wrong with:

   >assert(&Y[20] <= &X[0][0] && X[20][20] >= Y[0]);

   >(apart from the obvious fact that it's not portable)?

   Well, another obvious fact is that you probably meant '||', not '&&':-).

   Seriously, the problem with this is that it's not just "not portable",
   it's *UNDEFINED BEHAVIOUR* to compare pointers that are not pointing
   inside the same array -- a perfectly compliant compiler could make
   demons fly out of your nose as a consequence of this code.

Couldn't we do something like
// select the correct allocator for the memory model
typedef Allocator::diff_t diff_t   // I think that's what it calls ptrdif_t

diff_t value1 = &Y[20] - &X[0][0]
diff_t value2 = &X[20][20] - &Y[0]
assert(value1 <= 0 || value2 >= 0);

If my memory holds the difference type for the allocator functions is
defined to hold the difference between any two pointers in the memory
model.

Or is this an oversite in the draft, to seem to allow this?

I could look at the wording some more, and in other places but what is
the intent here?

[snip]
[ lots of neat portable ideas, that can be implemented if, the above
  is true. ]

[snip]
[class preconditions/postconditions ]

assert's and runtime test aren't great but they can do this, is a
semiportable way.  The real question is can we express what we want to
assert?

Eric
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]