From: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Subject: Re: Pointer comparisons
Organization: Computer Science, University of Melbourne, Australia
Date: Mon, 21 Dec 1992 12:39:25 GMT

pat@frumious.uucp (Patrick Smith) writes:

>"Pointers ... may be compared".  Does this mean any pair of pointers
>may be compared, or some pairs may be compared?  It certainly suggests
>"any pair" to me, but some might interpret it as "some pairs".

I would interpret it to mean that any pair of pointers may be compared.

>"the result depends on the relative positions ... in the address
>space."  What does this mean?

I think that this is intended to convey a general idea of the intent of the
standard-writers. I don't think it has any direct implications with
regard to the behaviour of an implementation. Perhaps it would be
more suitable as part of the commentary rather than as part of the
standard itself.

>"If two pointers point to elements of the same array ...".
>What if they point to members of elements?
>
>   struct X { int a; int b; };
>   X x[2];
>
>Must it be true that &x[0].a < &x[1].a?  What about &x[0].b < &x[1].a?

Not according to the ARM as it stands. There might be a reasonable
case for extending the guarantee to these additional cases.

>Let me try to be constructive for a change.  Would something
>similar to the following be reasonable?  (It would clearly need
>much more careful wording and attention to details.)
>
>1) Any two pointers to the same type may be compared, with any of
>   the relational operators.
>
>2) In general, the results of the comparisons need not have anything
>   to do with the objects to which the pointers point.  For example,
>   it is possible that p and q point to the same object, but p != q.
>   (But see below.)

I don't think that this is reasonable. It is necessary to be able to
detect when two pointers point to the same object in order to
write correct and efficient assignment operators in many cases.

>3) The relational operators define a total ordering on the set of
>   pointers of each type.  (All the normal rules, including
>   transitivity.)
>
>4) If two pointers p and q (of the same type) are obtained through
>   sequences of "normal" operations, then
>
>      p == q   <==>   p and q point to the same object
>
>      [list of other reasonable properties of pointer comparisons]
>
>For rule (4), "normal" operations would include things such as
>the built-in & operator, adding integers to pointers to array
>elements, normal casts (eg. derived class pointer to base class
>pointer), and calls to standard library functions.  It would
>specifically exclude casts whose meaning is not defined by the
>standard (eg. casting an integer to a pointer) and calling an
>extern "C" function.  (Actually, one could develop a notion of a
>C function which only does "normal" operations and permit
>calling such a function.  (Is there already a concept of strictly
>conforming C function, as opposed to program?))

There is no need for these new notions of "normal" operations or
"strictly conforming functions". The "normal" operations should
just be all operations whose results are defined by the standard.
(See my earlier responses to John Skaller's posts.)

>On systems where a pointer can be treated as an integer address,
>this should pose no problems.
>
>On systems where a pointer is composed of a segment identifier
>and an offset, the compiler might arrange that the "normal"
>operations would never change the segment identifier.
>Comparisons could then be done by just comparing the
>segment identifier and offset.  If two pointers to the same object
>have different segment identifiers, then the programmer must have
>applied some un"normal" operation, so it's OK if the pointers
>compare unequal.

This is exactly what C compilers for DOS systems currently do.
It should be straightforward to apply the same approach for the
386 memory models where pointers are 48 bits.

-- 
Fergus Henderson             fjh@munta.cs.mu.OZ.AU      
This .signature virus is a self-referential statement that is true - but 
you will only be able to consistently believe it if you copy it to your own
.signature file!
Xref: sparky comp.std.c++:1893 comp.std.c:3255