if(p)

John Bruner jdb at mordor.UUCP
Sat Nov 2 07:29:42 AEST 1985


In article <366 at graffiti.UUCP> peter at graffiti.UUCP (Peter da Silva) writes:
>Um, treating an all-0 value as a pointer? But what operation do you do on
>pointers apart from dereferencing that could be construed as doing something
>with a *pointer* as opposed to doing something with a *variable*? Sounds like
>some net.bizarre sort of tagged architecture, in which case you can throw
>portability out the window anyway. I mean, what would this do to implicit type
>conversion, just for starters? OK, let's rephrase that. What sort of
>architecture could you actually implement 'C' on, and reasonably easily port
>programs to and from, that wouldn't let you use 0 as a pointer?

A few months ago I described the problems that the incorrect assumption
that (foo *)0 has an all-zero-bits representation caused when we were
attempting to transport C programs to our machine, the S-1 Mark IIA.

The Mark IIA has a 36-bit word.  Pointers are partitioned into a
5-bit tag and a 31-bit address.  The different tag values specify
different protection rings (ring 0 == kernel, ring 3 == user) and
special pointer types (nil, self-relative).  [We did not use
self-relative pointers in C.]  The tag values 0 and 31 are reserved
as invalid.  Any attempt to manipulate a pointer with an invalid
tag causes a trap.  Since most integers will be either small
negative or positive numbers, this helps to detect the use of
uninitialized pointers.

Just as floating-point numbers are manipulated differently than
integers, there are instructions to copy and manipulate pointers.
An attempt to copy an all-zero word with a pointer instruction
causes a trap.

Pointers with the "nil" tag can be copied, but they cannot be used
in address expressions.  Of course, "nil" cannot be de-referenced.

Pointer to integer coercions are possible (just as conversions
between floating-point and integers are possible).  However,
K&R does not guarantee that all integers can be copied into a
pointer.  It only guarantees that (given sufficiently large
integers, conversion from pointer to integer to pointer will
return the original pointer.  In particular, it is *not*
guaranteed that you can always do something like this:

	p = (char *)10;

After fighting the tide of sloppy coding practices, we finally
gave in and changed the meaning of tag 0 (in microcode) and
adopted an all-0 bit pattern for NULL.  It was wrong, it was
ugly, but it was the only expedient thing to do.

If C is to survive as a language it must be allowed to escape
its PDP-11 origins (and I include the VAX [and to some degree
the 68000] in this category).  (foo *)0 is not an all-zero
bit pattern; it may not even be a memory address.  Although
this may be the implementation on some (or even most) machines,
the abstract idea should not be confused with the most common
implementation.
-- 
  John Bruner (S-1 Project, Lawrence Livermore National Laboratory)
  MILNET: jdb at mordor [jdb at s1-c.ARPA]	(415) 422-0758
  UUCP: ...!ucbvax!dual!mordor!jdb 	...!seismo!mordor!jdb



More information about the Comp.lang.c mailing list