[comp.std.c] pointer comparisons in dpANS C

chris@mimsy.UUCP (Chris Torek) (10/19/88)

[followups redirected to comp.std.c]
In article <8696@smoke.ARPA> gwyn@smoke.ARPA (Doug Gwyn) writes:
>The key is that you are allowed to portably compare pointers only in two
>cases:  at least one pointer is a null pointer, or both pointers are
>pointers into the same object.  This means that the fact that p1==p2 for
>pointers to distinct objects is not a problem, since such comparison is
>"undefined". ...

This point (which is true) makes me wonder about something.  Consider
a program which allocates object memory with `malloc'.  Each object has
pointers to other objects, but does not have backpointers---e.g.,
a singly linked list.  Now we have a removal routine:

	delete(listhead, obj)
		struct list **listhead;
		struct list *obj;
	{
		register struct list **p;

		for (p = listhead; *p != NULL; p = &(*p)->next) {
			if (*p == obj) {
				*p = obj->next;
				free((char *)obj);
				return;
			}
		}
		panic("object not in list");
		/* NOTREACHED */
	}
	...
		struct list *head = NULL;
		... /* put objects in the list */ ...
		delete(&head, thisobj);
		...

A perfectly ordinary routine, but it has a significant implication:
Every address returned by malloc must compare as not distinct from
every other address, lest this routine delete the wrong object.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

karl@haddock.ima.isc.com (Karl Heuer) (10/20/88)

In article <14061@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
>In article <8696@smoke.ARPA> gwyn@smoke.ARPA (Doug Gwyn) writes:
>>The key is that you are allowed to portably compare pointers only in two
>>cases:  at least one pointer is a null pointer, or both pointers are
>>pointers into the same object.  This means that the fact that p1==p2 for
>>pointers to distinct objects is not a problem, since such comparison is
>>"undefined". ...
>
>This point (which is true) makes me wonder about something.  ...

I have to disagree with both of you.  As I interpret the rules, the relational
operators (<, etc) require that the operands belong to the same aggregate, but
the equality operators (==, !=) can be applied to any valid pointers.  (This
may imply, for certain architectures, that comparing pointers for equality is
harder than comparing integers.)

Unfortunately I can't find a definitive statement in the dpANS or Rationale
that supports my interpretation, and the line about the equality operators
being analogous to relationals argues against it.  But surely this wasn't the
intent of the Committee; it invalidates too much working code!

>Every address returned by malloc must compare as not distinct from
>every other address, lest this routine delete the wrong object.

"If two pointers ... compare equal, they point to the same object."  Of course
this is irrelevant if the analogy to relational operators is upheld.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
(Chris, when you change the subject line, please leave a `was:' remnant so the
newsreaders can track it.)

chip@ateng.ateng.com (Chip Salzenberg) (10/22/88)

According to chris@mimsy.UUCP (Chris Torek):
[sample program deleted]
>Every address returned by malloc must compare as not distinct from
>every other address, lest this routine delete the wrong object.

Quite.

As a data point:  C compilers for the '286, when generating "far" pointers
(16 bits segment, 16 bits offset), generally ignore the segment portion of
pointers when testing their relative magnitudes ("<", ">=", etc).  However,
tests for equality and inequality ("==", "!=") always compare all 32 bits.

I understand why this choice might be made, and it certainly passes Henry's
test program.  Nevertheless, it can be surprising -- perhaps incorrect? --
that:

	((p >= q) && (p <= q))

is not the same as:

	(p == q)

Ah well, yet another '286 "feature".
-- 
Chip Salzenberg             <chip@ateng.com> or <uunet!ateng!chip>
A T Engineering             Me?  Speak for my company?  Surely you jest!
	   Beware of programmers carrying screwdrivers.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (10/23/88)

In article <1988Oct21.143640.10468@ateng.ateng.com> chip@ateng.ateng.com (Chip Salzenberg) writes:
>According to chris@mimsy.UUCP (Chris Torek):
>>Every address returned by malloc must compare as not distinct from
>>every other address, lest this routine delete the wrong object.

In case I misled anyone by a previous posting, (in)equality comparison
of pointers (having appropriate types) is supposed to work according to
the proposed ANS for C even when the pointers are not into the same
object.  It is the order-relational comparison that requires that the
pointers be into the same object.

bill@twwells.uucp (T. William Wells) (10/24/88)

In article <14061@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
: [followups redirected to comp.std.c]
: In article <8696@smoke.ARPA> gwyn@smoke.ARPA (Doug Gwyn) writes:
: >The key is that you are allowed to portably compare pointers only in two
: >cases:  at least one pointer is a null pointer, or both pointers are
: >pointers into the same object.  This means that the fact that p1==p2 for
: >pointers to distinct objects is not a problem, since such comparison is
: >"undefined". ...
:
: This point (which is true) makes me wonder about something.  Consider
: a program which allocates object memory with `malloc'.  Each object has
: pointers to other objects, but does not have backpointers---e.g.,
: a singly linked list.  Now we have a removal routine:

Guys, you are going to have to convince me of this. From everything I
see, two pointers are not allowed to compare equal *unless* they
point to the same object.  Section 3.3.9 is very clear on this point.

It is only for tests other than equality or nonequality that the
pointers must point within the same object.

---
Bill
{uunet|novavax}!proxftl!twwells!bill

chris@mimsy.UUCP (Chris Torek) (10/25/88)

In article <114@twwells.uucp> bill@twwells.uucp (T. William Wells) writes:
>... From everything I see, two pointers are not allowed to compare equal
>*unless* they point to the same object.  Section 3.3.9 is very clear on
>this point.

*There* it is!  Thanks for the section number.  (The current draft, along
with all the junk mailed with it to alternate members---I borrowed it from
one---sits on my desk as a pile of paper more than 3 cm high.  No wonder
I can never find anything in it....)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris