Subject: Re: NULL return value checking
To: Gary Thorpe <gat7634@hotmail.com>
From: Andy Isaacson <adi@hexapodia.org>
List: tech-kern
Date: 04/23/2002 18:36:21
This doesn't belong on tech-kern, but...
On Tue, Apr 23, 2002 at 06:44:20PM -0400, Gary Thorpe wrote:
> As far as I know, using NULL explicitly makes programs more portable (a low
> priority for code specific to any OS kernel obviously).
False. Replacing every occurrence of "if(p == NULL)" with "if(p)" or
"if(p == 0)" or even "if(p == '\0')" (ewww!) [1] has precisely zero impact
on the portability of the code.
The place where the difference between NULL and 0 might have
significance is as an argument to a function whose signature is not
known to the compiler (varargs, or a function for which a prototype is
not in scope), and when doing memset() of memory which might include a
pointer. [2]
> I have always seen NULL defined as 0. However, NULL simply represents an
> invalid value for a pointer, and its actually value is PLATFORM SPECIFIC as
> far as ANSI compliant code goes. That is, a platform can define NULL to be
> any value which the platform would interprit to be an invalid pointer.
That may well be, but ISO/IEC 9899:1999 6.3.2.3 (the ISO C99 standard)
requires that
An integer constant expression with the value 0, or such an
expression cast to type >void *<, is called a *null pointer
constant* (55). If a null pointer constant is converted to a
pointer type, the resulting pointer, called a *null pointer*, is
guaranteed to compare unequal to a pointer to any object or
function.
[...]
Any two null pointers shall compare equal.
55) The macro NULL is defined in <stddef.h> (and other headers) as
a null pointer constant; see 7.17.
[ >bold monospace< and *italic* text so indicated; footnotes eliminated.
Typo of "as" for "is" in the footnote is in the original.]
> Assuming it is zero is technically incorrect.
Assuming that the bit pattern stored in a pointer storing a "null
pointer" is all-bits-zero is incorrect. Assuming that "p = 0" sets p to
a null pointer is explicitly sanctioned by the standard.
[1] '\0' is "[a]n integer constant expression with the value 0", thus
satisfying the requirements to be considered a null pointer constant.
[2] I recall some debate about what types you were actually allowed to
memset(, 0, ); certainly unsigned char is OK, signed char is
probably OK, but there exist implementations where an all-bits-zero
pointer is NOT == NULL. I believe the AS/400 may be one. Certainly
there are floating point representations where all-bits-zero is not
a valid FP number. Search the standard for "trap representation"
for relevant stuff.
pedantically yours
-andy