Subject: Re: NULL return value checking
To: tld <tld@tld.digitalcurse.com>
From: Greg A. Woods <woods@weird.com>
List: tech-kern
Date: 04/24/2002 04:45:58
[ On Wednesday, April 24, 2002 at 10:20:58 (+0100), tld wrote: ]
> Subject: Re: NULL return value checking
>
>  >     An integer 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 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.
>  >
>  > I.e. no matter how it's defined, NULL == 0.
> 
> Oh, well, then gcc-i386 is not following the standards: 0x00000000
> references a VERY VALID memory address (the vector table)

No, that's not exactly true (while GCC may not be fully standards
compliant, your interpretation of the ISO C rule I quoted above, and
your conclusion that GCC is in violation of that rule, are both
incorrect).

What the standard means is that no address of a valid object or function
will ever be equivalent to zero.  A compliant C compiler will not
allocate any object (or function) storage which will be at an address
equivalent to an integer constant expression with the value 0.

Processors and operating systems might well have valid addresses
equivalent to zero, but you are not supposed to be able to define a C
object or function that will ever by accident or design be located at
that address (not that C allows you to define the location any object
will be allocated at in the first place, of course).

Note that so far as I can tell there's no rule in the C standards that
prohibit a compiler from allowing a dereference of a null pointer, and
thus it's possible to assign a pointer the value of zero and then at
least try to access the memory at an address of zero (assuming there's a
bit-for-bit correspondence between integer zero and pointer zero), and
as such it may be possible to access whatever's stored at location zero
from within a standards conforming C program as compiled by a standards
compliant C compiler.  On the other hand, as der Mouse says, doing so
may also result in any number of other undefined actions too.  Unix
programmers have come to value the fact that most unix implementations
will signal SIGSEGV if their programs accidentally dereference NULL.

> A more appropriate value would be 0xffffffff (unless someone has 4gb or 
> a mmap, that is). IMHO assuming NULL == 0 is bad practice if portability 
> is a target.

Assuming NULL is defined _is_ bad practice for extreme portability.

However assuming a null pointer constant is equivalent to zero is now
absolutely guaranteed (for any compliant compiler :-), and it has
implicitly been that way since the very dawn of C.

-- 
								Greg A. Woods

+1 416 218-0098;  <gwoods@acm.org>;  <g.a.woods@ieee.org>;  <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>