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

M.J.Shannon mjs at sfmag.UUCP
Mon Sep 16 00:23:30 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.

Koenig is correct both in the rules cited and the conclusions reached.  Your
statement immediately above is also correct, but your conclusion below
("if (p)" is not portable) is incorrect.

>   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.

Incorrect.  It is the compiler's responsibility to interface with the host
architecture, not the programmer's.  The compiler is required to generate code
which determines whether the pointer "points to no object of the given type"
in the host architecture or not for the fragment "if (p)".

>   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 *).

Comments above are all wrong.  Clearly specified in K&R (and, I believe, ANSI
C drafts) is the statement that the (integer) constant 0 may safely (and
correctly) compared to a pointer of any type to determin 0th order validity of
said pointer.  Your statement above is true, but only because different
implementations and/or environments define NULL as something other than "0".

>    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 */

While the preceding fragment is guaranteed to be correct in all (valid)
implementations of C, your moral above is incorrect.  At the level of C source
(in particular, not at the level of the hardware), it is a guarantee that the
integer constant 0 (independant of its representation in the actual hardware)
*IS* the canonical null pointer for all pointer types, *BY DEFINITION*.  This
is specified explicitly in all the specifications of the language I've ever
seen.

> NULL is defined as "(char *)0", not as "0" on any sensible system and

Wrong.  *Some* implementations provide some header file which may define NULL
as something other than "0".  Those that do so are misleading their users, or
intend its use only in comparisons of "char *" types.

> 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 */

No, not bad.  Perfectly legitimate and proper *on implementations which
properly implement the C language*.

>   if(p != (anytype *)0)	/* GOOD */

Good only if the type of p is "anytype *".

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

Stu, if you'd like to carry this argument further, let's do so offline (via
mail).  No need to further inflame the other good folks on the net.
-- 
	Marty Shannon
UUCP:	ihnp4!attunix!mjs
Phone:	+1 (201) 522 6063
Disclaimer: I speak for no one.



More information about the Comp.lang.c mailing list