Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!uunet!seismo!husc6!think!ames!oliveb!sun!gorodish!guy
From: guy%gorodish@Sun.COM (Guy Harris)
Newsgroups: comp.lang.c
Subject: Re: What is NULL?  There is no right answer!
Message-ID: <23368@sun.uucp>
Date: Tue, 14-Jul-87 05:14:37 EDT
Article-I.D.: sun.23368
Posted: Tue Jul 14 05:14:37 1987
Date-Received: Thu, 16-Jul-87 03:37:08 EDT
References: <1810@megaron.arizona.edu>
Sender: news@sun.uucp
Lines: 63
Keywords: NULL 0 pointer C

I can definitely tell you one thing NULL is *not*; it is not the
fundamental representation of a null pointer in C.  The official C
language representation of a null pointer of a particular type is the
integral constant 0, coerced to a pointer of that type.  This
coercion occurs automatically in comparisons:

	char *p, *q;

	/*
	 * Yes, both of these are comparisons against null pointers.
	 */
	if (p == 0 || !q)

assignments:

	p = 0;

and, if you have an implementation of C that supports function
prototypes (which, barring any massive surprises, implementations of
ANSI standard C will be once the standard is official), most, but NOT
all, procedure calls:

	/*
	 * Don't try this one at home, kids, unless you have a function
	 * prototype for "setbuf" in scope!
	 */
	setbuf(stdout, 0);

but not

	execl("/bin/sh", "sh", "-c", "rm -rf /", 0);

Unless some function prototype syntax appears that enables you to
tell the compiler that the last argument to "execl" is of type
"char *", the compiler won't be able to figure out that the last
argument should be of type "char *" and that the 0 must be coerced to
that type.  Thus, you must do

	execl("/bin/sh", "sh", "-c", "rm -rf /", (char *)0);

instead.  Furthermore, if your implementation of C doesn't support
function prototypes,

	setbuf(stdout, 0);

won't work either, since the compiler can't be told what the types of
the arguments to "setbuf" are; in this case, as well, you must do

	setbuf(stdout, (char *)0);

Whether NULL is defined as 0 or 0L or (char *)0 or (void *)0 is
irrelevant.  NULL is merely syntactic sugar around 0, which is a
token used to construct null pointer constants; there are plenty of
programs that are on a sugar-free diet and use 0 rather than NULL.
If they do not include any casts necessary to cause the
aforementioned coercions of 0 to a null pointer constant of the
appropriate type, defining NULL as 0L or (char *)0 or (void *)0 or
whatever isn't going to make those programs work any better on
machines where the bit pattern for 0 and for null pointers of some
types aren't the same.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com