use of if (!cptr) and if (cptr), where cptr is a *

R v/d Born reinier at cwi.nl
Tue Jul 25 22:16:47 AEST 1989


In article <10100 at mpx2.mpx.com> erik at mpx2.mpx.com (Erik Murrey) writes:
>
>In article <93 at microsoft.UUCP>
>>In article <10099 at mpx2.mpx.com> erik at mpx2.mpx.com (Erik Murrey) writes:
>>>
>>>Would (!sptr) break anywhere?  Should it be discouraged?
>>
>>It will break if NULL != 0.  This is rare in my experience.  In fact
>>so rare that most programs would break in such an environment.  Besides
>>....
>Yes, I know, but what happens when sizeof(int) != sizeof(char *)?  My
>original question wasn't stated too clearly.
>
>Suppose a char * is 6 bytes, and an int is 4.  Suppose the upper 2 bytes
>are used as some sort of descriptor.  Now suppose malloc() returns
>.....
>
>if (cptr == 0) ?  Does the compiler cast the cptr to an int, and loose
>the descriptor?  (And tell is that it is null?)
>.....
>Erik Murrey

Let us take a look at the pANS.

1) section 3.3.3.3: (about the ! operator)
   The result of the logical negation operator ! is 0 if the value of its
   operand compares unequal to 0, 1 if the value of its operand compares
   equal to 0. The result type is int.

2) section 3.2.2.3: (about NULL and 0)
   An integral constant expression with the value 0, or such an expression
   cast to type void *, is called a null pointer constant. If a null pointer
   constant is assigned to or compared for equality to a pointer, the constant
   is converted to a pointer of that type. Such a pointer, called a null
   pointer, is guaranteed to compare unequal to a pointer to any object or
   function.

   Two null pointers, converted through a possible different sequence of casts
   to pointer types, shall compare equal.

(sorry for the loss of italics and special fonts :-)

So we may conclude that the expression:
	(! cptr)
is evaluated as
	(cptr == (cast to cptr type) 0)
and therefor never fail to detect NULL.

Likewise the value of the test expression in an if, while, etc. is compared
with 0 (see sections on statements). So
	if (ptr)
is equivalent with
	if (ptr != 0)
which is equivalent with
	if (ptr != (ptr type) 0)

Note that pANS doesn't prescribe the use of a pointer consisting of all 0s
to represent NULL, nor does it say anything about the sizes of a pointers
(which may differ for different objects they point to).
It rather forces the compiler to reserve a special representation and
convert 0 to that representation before performing the comparison.

So things like

	f( ptr )
	int *ptr;
	{
		if (ptr)
		....
	}

	...
		f( 0 );

won't work when, for instance, using the compiler I am working on.
But what the heck, that should teach people writing such code (:-)

Reinier van den Born
Parallel Computing
s-nail: Postbus 16775, 1001 RG Amsterdam, The Netherlands
e-mail: reinier at cwi.nl



More information about the Comp.lang.c mailing list