home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.std.c++
- Path: sparky!uunet!elroy.jpl.nasa.gov!usc!zaphod.mps.ohio-state.edu!uunet.ca!frumious!pat
- From: pat@frumious.uucp (Patrick Smith)
- Subject: Pointer comparisons
- Message-ID: <BzDs2x.wA@frumious.uucp>
- Date: Thu, 17 Dec 1992 01:56:56 GMT
- Reply-To: uunet.ca!frumious!pat
- References: <1992Dec9.191606.5665@lucid.com> <BzCG7K.2sG@frumious.uucp> <1992Dec16.202711.22367@bcrka451.bnr.ca>
- Organization: None
- Lines: 162
-
- (I hope nobody minds my changing the subject line to something
- a little more succinct.)
-
- While responding to a previous posting, I looked up what the
- draft C++ standard (the September 17 version) had to say about
- pointer comparisons. Here's an extract from section 5.9:
-
- Pointers to objects or functions of the same type (after pointer
- conversions) may be compared; the result depends on the relative
- positions of the pointed-to objects or functions in the address
- space.
-
- Two pointers to the same object compare equal. If two pointers
- point to nonstatic data members of the same object, the pointer
- to the later declared member compares higher provided the two
- members [are] not separated by an access-specifier label (11.1)
- and provided their class is not a union. If two pointers
- point to nonstatic members of the same object separated by an
- access-specifier label (11.1) the result is unspecified.
- If two pointers point to data members of the same union, they
- compare equal (after conversion to void*, if necessary).
- If two pointers point to elements of the same array or one beyond
- the end of the array, the pointer to the object with the higher
- subscript compares higher. Other pointer comparisons are
- implementation dependent.
-
- Unfortunately, my copy of the C standard isn't at all handy, so
- I can't compare with what it says.
-
- Some of this is quite unclear to me.
-
-
- "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".
-
-
- "the result depends on the relative positions ... in the address
- space." What does this mean? Must one convert the pointers into
- actual addresses and return the result of comparing those addresses?
- Probably not, given that "[o]ther pointer comparisons are
- implementation dependent." Maybe one is to convert the pointers
- into addresses and apply some (arbitrary) function to those addresses?
- If so, why would one want such a condition? What happens if there's
- more than one address space? This clause seems reasonable to me if
- interpreted as "the general intent of pointer comparison is to compare
- addresses", but perhaps it's not suitable as part of the specification
- of the language.
-
-
- "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?
-
-
- "If two pointers point to data members of the same union, they compare
- equal (after conversion to void*, if necessary)." This one seems
- clear enough, but may have a trap for the unwary.
-
- class A {};
- class B {};
- class C : public A, public B {};
- union D {
- B b;
- C c;
- } d;
-
- Here the comparison &d.c == &d.b is legal, but might return 0
- (it compares pointers to d.b and the B part of d.c). To compare
- pointers to d.c and d.b themselves, one should explicitly cast
- to void*. Ouch.
-
-
- 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.)
-
- 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
-
- If p and q point to elements of the same array, or to
- subobjects of _different_ elements of the same array,
- then they compare the same way as the indexes of the
- elements in the array.
-
- As above when p and q point to members of the same (non-union)
- object.
-
- If p and q point to members of the same union object, then
- p == q if either
-
- - the members have the same type (ignoring const and volatile)
-
- or
-
- - p and q are void* pointers and were obtained by converting
- directly from pointers to the types of the members, with
- no intermediate conversions (again ignore const and
- volatile everywhere).
-
- If neither of these conditions is met, p == q is
- implementation-defined.
-
-
- 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?))
-
-
- 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.
-
- One might add a library function sameObject(p,q) which would
- indicate whether p and q point to the same object, no matter
- how p and q were obtained.
-
-
- If we ignore the question of how much existing code this would
- break, is this a reasonable suggestion?
-
- And how much existing code would this break (that isn't already
- broken)? Note that it doesn't break any code that restricts
- itself to "normal" operations.
-
- --
- Patrick Smith
- uunet.ca!frumious!pat
- pat%frumious.uucp@uunet.ca
-