Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/18/84; site rlgvax.UUCP
Path: utzoo!linus!philabs!cmcl2!seismo!rlgvax!guy
From: guy@rlgvax.UUCP (Guy Harris)
Newsgroups: net.lang.c
Subject: Re: offsets in structures.
Message-ID: <204@rlgvax.UUCP>
Date: Tue, 16-Oct-84 19:19:23 EDT
Article-I.D.: rlgvax.204
Posted: Tue Oct 16 19:19:23 1984
Date-Received: Thu, 18-Oct-84 00:46:11 EDT
References: <393@orion.UUCP> <5172@brl-tgr.ARPA>, <6542@mordor.UUCP> <5272@brl-tgr.ARPA>, <196@rlgvax.UUCP> <5319@brl-tgr.ARPA>
Organization: CCI Office Systems Group, Reston, VA
Lines: 66

> I don't want to repeat all the earlier arguments, but consider:
> A null pointer can be produced legally by arithmetic operations,
> as well as by hard-coded (foo *)0 constants in the source.  To
> use a special nil value would require run-time checks to be applied
> to much pointer arithmetic.  This is contrary to the intent of C.

If by "produced legally by arithmetic operations", you mean

	char *foo;
	int bar;

	foo = (bar - bar);

that's false.  When K&R refers to null pointers, it always refers to
"the constant 0", specifically excluding anything but the number "0" in
a source program (or #define constant expanding to that number):

	7.14 Assignment operators

	...However, it is guaranteed that assignment of the constant
	0 to a pointer will produce a null pointer distinguishable
	from a pointer to any object.

and

	7.7 Equality operators

	A pointer may be compared to an integer, but the result is
	machine dependent unless the integer is the constant 0.

Converting "an object of integral type" to a pointer, and back to
an integer, "always carries an integer converted form a pointer back into
the same pointer", but that merely means that an integer *variable* having the
value 0 must map into a pointer which, when mapped into an integer, maps into
the value 0.  This can be implemented by an bit-for-bit identity mapping
of pointers to integers and vice versa (BTW, I'd be the first to admit
that not only our 16-bit "int", 32-bit pointer 68000 C compiler, but AT&T's
68000 C compiler when built with 16-bit "int"s, and every other 16-bit
"int", 32-bit pointer C compiler, violates this; it implies that an "int"
must have at least as many distinct values as a pointer).

On a machine on which a null pointer had some special non-zero bit value, this
would mean that

	char *p, *q;
	int foo;

	p = 0;
	q = foo - foo;
	if (p != q)
		printf("Not equal\n");

would print "Not equal".  So what?  As stated above, the C Reference Manual
refers to null pointers as being conversions of *the constant* 0 to a
pointer value; since the only integer value which has to be converted to
a null pointer is a constant, there's no need for any run-time checks.

Frankly, I think a C implementation with all-zero null pointers on a machine
which strongly encouraged you to use some special non-zero pattern for
null pointers would violate C's charter much more; it would mean the C
implementation wasn't as close to the machine as it could be.  If the
"native" implementation language on the machine wasn't C, you'd have a real
pain interfacing to it.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy