if (p), where p is a pointer (REAL portability)

Stuart Friedberg stuart at rochester.UUCP
Fri Sep 13 14:33:23 AEST 1985


[S. Friedberg]
> [A. Koenig]
> > [forgot original poster, sorry]

> > With all this talk about NULL pointers not necessarily being equal to 0,
> > I'm no longer sure what is and isn't portable code.
> >	if (ptr)
> >	   <statement>
> > Will this work correctly on a machine where NULL is not 0?  Does it really
> > need to say
> >	if (ptr != NULL)
> No, you don't need to say NULL explicitly.  The relevant rules are:
[relevant rules elided]
> ... the usage is portable.  If NULL is not defined
> as 0, the very definition of NULL is non-portable.

I have to disagree with A. Koenig's reply.  The rules he cites are
accurate, but the conclusions are unsafe.

A constant zero IS safely converted into a "null" pointer of the
appropriate type.  IT IS NOT THE CASE that a "null" pointer of an
arbitrary type is converted to or represented by all zero bits.
  char *p;
  if (p)			/* NOT PORTABLE */

Moreover, saying that NULL must be defined as zero is putting the cart
before the horse.  NULL must be defined as an invalid (char *) pointer
and if your machine architecture wants that to be 0x555555, then that
is what NULL should be defined as.  It is coincidental and NONPORTABLE
that NULL is usually defined as 0.
  char *p;
  if (p != 0)			/* NOT PORTABLE */
  if (p != NULL)		/* PORTABLE */

NULL is NOT guaranteed to be canonical "null" pointer for any type
other than (char *).
   struct foo *f;
   if (f != NULL)		/* NOT PORTABLE */
   if (f != (struct foo *)0)	/* PORTABLE */

Moral:  It is an unfortunate accident of fate that a word or longword
with all zero bits can serve as a canonical "null" pointer for all
pointer types on most machines.  Yes, it works on most machines. No,
it is not portable and if you really want PORTABLE code, use this idiom:
   anytype *p;
   if (f != (anytype *)0)	/* PORTABLE */

NULL is defined as "(char *)0", not as "0" on any sensible system and
if your architecture is one where null pointers of all types are zeroed
integers, there will be NO OVERHEAD using the suggested idiom, because
even trivial compilers will generate identical code for
  if(p)			/* BAD */
  if(p != (anytype *)0)	/* GOOD */

Stu Friedberg  {seismo, allegra}!rochester!stuart  stuart at rochester



More information about the Comp.lang.c mailing list