[comp.lang.c] non-zero NULL pointers

scs@athena.mit.edu (Steve Summit) (11/19/88)

In article <4509@aldebaran.UUCP> jimp@cognos.UUCP (Jim Patterson) writes:
>I know of at least one system where the system convention is not 0;
>Data General MV systems have instructions which take -1 as the null
>pointer value, and this has persisted through many system call
>conventions as well. However, the C implementation still considers a
>null pointer to be 0 even though this requires quite a bit of "glue"
>around some system calls to interface between the two formats.
>Requiring that the "null pointer constant" be 0, as ANSI C does, just
>makes any other implementation painfully difficult (and is begging for
>problems when porting software as well).

If the null pointer convention is not 0, the conversion can be
done by the compiler at compile time.  No run-time glue is
necessary.

We only discuss this every month or so.  The compiler can tell
that "0" is a "null pointer constant," as long as it is in an
initialization, assignment, comparison, or function return
context.  It can then generate whatever bit pattern is
appropriate.

     Q:	Wait a minute.  Does that mean that if I write
		register char *p = 0;
	the compiler could generate
		move #FFFF, r4
	?

     A:	Precisely.

The fact that the null pointer constant in C is "0" does not,
repeat not, place any restrictions on the bit pattern used by the
generated code.  Using "0," rather than some machine-dependent
value, increases portability: the translation to the machine-
dependent value is made by the compiler, along with all
of the other machine-dependent translations.  (Sadly, the use of
0 as the null pointer constant has increased programmer confusion
more than it has decreased machine dependencies.)

If, in fact, the compiler for the Data General MV systems
referred to above generates code for null pointers having a bit
pattern of 0, requiring run-time code to translate them to -1 at
the system call interface, it may have been to defend against
(unportable, incorrect) code which failed to differentiate null
pointer constants from integer zeroes in the one context where
the compiler can not distinguish them: function calls.
Programmers must use explicit casts to the correct pointer type
when passing null pointers to functions.  (This restriction is
relaxed if an ANSI-style function prototype is in scope, since
function call context is then equivalent to assignment context.)

If you don't understand this, or have questions, for God's sake
don't post a followup article.  All of the questions and all of
the attendant confusion have been discussed on this newsgroup
countless times before.  (Send mail if you must.)

                                            Steve Summit
                                            scs@adam.pika.mit.edu

chris@mimsy.UUCP (Chris Torek) (11/20/88)

In article <8058@bloom-beacon.MIT.EDU> scs@athena.mit.edu (Steve Summit)
writes:
>The fact that the null pointer constant in C is "0" does not,
>repeat not, place any restrictions on the bit pattern used by the
>generated code.  Using "0," rather than some machine-dependent
>value, increases portability: the translation to the machine-
>dependent value is made by the compiler, along with all
>of the other machine-dependent translations.  (Sadly, the use of
>0 as the null pointer constant has increased programmer confusion
>more than it has decreased machine dependencies.)

Right.

One way to perhaps clear up some of the confusion is to think of it
this way:  If C had had a `nil' keyword, one would not write

	char *p = 0;

but rather

	char *p = nil;	/* almost like `var p: ^char; begin p := nil;' :-) */

Now, if we had this keyword, we could also write:

	int execl(char *prog, char *av0, ...);

and a call like

	execl("foo", nil);

would know to cast the `nil' into a `char *' (which might very well
produce the binary value `-1'), while the call

	execl("foo", "foo", nil);

could correctly complain that it has no idea what *kind* of nil
to provide.

But C does not have the `nil' keyword; instead, it has `0'.  When the
compiler sees `0', it asks whether the `0' is filling in for `nil'.  If
so, it provides the appropriate cast.  If it cannot tell, it *assumes*
that the 0 is really a 0!

The moral?  Put in the cast.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris