Xref: utzoo comp.arch:5218 comp.lang.c:10819
Path: utzoo!attcan!uunet!husc6!bloom-beacon!mit-eddie!ll-xn!ames!oliveb!sun!gorodish!guy
From: guy@gorodish.Sun.COM (Guy Harris)
Newsgroups: comp.arch,comp.lang.c
Subject: Re: null pointers (was: negative addresses)
Message-ID: <57254@sun.uucp>
Date: 20 Jun 88 20:26:48 GMT
References: <226@proxftl.UUCP> <3100003@hpmwtla.HP.COM>
Sender: news@sun.uucp
Followup-To: comp.lang.c
Lines: 64

> ANSI C is not C.  Prototypes do not exist in C.  Please show me where in
> K&R that it states that "0" refers to the NULL pointer irrespective of the
> underlying implementation.

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.  A pointer to which 0
	has been assigned is guaranteed not to point to any object, and will
	appear to be 0; in conventional usage, such a pointer is considered to
	be null.

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.

Next question.

> ...if "0" does refer to the null pointer, why do some systems have #define
> NULL (-1) in stdio?

Because the implementors were ignorant.  Any language implementation that
defines NULL as -1, and purports to be an implementation of C, is broken.

Next question.

> My statement regarding casting is correct, since not all pointers need be 
> of the same size.  Prototypes eliminate this annoyance, but I live with
> a compiler void of prototypes :-(

Your statement regarding casting was:

> 	#include 	/*stupid place for NULL*/
> 	...
> 	Foobar *foobar;
> 	for (foobar = first; foobar != (Foobar*)NULL; foobar = foobar->next)
> 	{
> 	}

> (For code to be truly portable, NULL must be cast to the appropriate pointer
> type every time it is used since it is nothing more than an integer bit
> pattern :-)

which is absolutely, positively, INcorrect.  The cast is totally unnecessary in
the "for" loop in question; the compiler is quite capable of figuring out that
0 or NULL must be converted to a null pointer of type "Foobar *" before
comparing it, and all valid C compilers will do so (if you know of a compiler
that does not, it is invalid - period).

Furthermore, as there are no function calls whatsoever in your example,
prototypes have no effect.

The ONLY place where you are required to cast NULL properly is when passing
arguments to a procedure; prototypes eliminate that unless you have a function
(such as "execl") that takes a variable number of arguments or otherwise cannot
have its calling sequence fully described by a prototype.  Any valid compiler
will perform the required conversion automatically in all other cases
(assignments and comparisons, as described above).