Date: Sun, 6 Nov 1994 17:16:02 -0500 From: aml AT world DOT std DOT com (Andrew M. Langmead) To: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Re: NULL pointers... heilig AT cs DOT und DOT nodak DOT edu (Zach Heilig) wrote: >Hmm... I would guess that having NULL != (void *) 0, even if it's not >supposed to be guaranteed to be that in the first place, would break more code >than we'd all like to imagine. I definitely vote for getting the protection >on address 0x0 to work. NULL will always equal (void *)0, but that is not the same as saying that the bit pattern for a NULL pointer is the same bit pattern as the integer value of 0. According to the Standard C spec, when a 0 or a (void *)0 is used in an assignment context to a pointer, the compiler will substitute the value of the NULL pointer valid for the pointer type on that system. (I guess that if the compiler can guarantee that it will never return a certain value as a pointer, even if it is potentially valid on the system, the compiler can return that value.) This means that if a system guarantees that a pointer whose bit pattern matches the integer value 31415927 is not a valid value for a pointer to int, when the compiler sees an assignment like: int * Pointer = 0; the compiler can (should?) generate code that assigns 31415927 to Pointer. Calling a function that is prototyped is like an assignment, so an uncast 0 is seen as a NULL (or using the symbol NULL if it is defined like #define NULL 0). If the integer value 0 is passed to a function that is not prototyped, or uses an ellipse to prevent type checking of arguments, the compiler will not see the 0 as a pointer assignment. When this happens, the code is only portable to systems that the representation of the NULL pointer is the same as an integer 0. Also doing things like memset()ing structures that contain pointers will not guarantee that the pointers are NULL pointers. In practice, most compilers use 0 as the NULL pointer unless there is a compelling reason not to. Systems that have no value for a pointer that is invalid tend to use 0. Systems that have a value for a pointer that is invalid may use that value, or if they want to be portable with code that makes unportable assumptions about NULL, may still use 0. Section 1 of the comp.lang.c Frequently Asked Questions post gives a very complete explanation of it all for those interested. But as everyone else has said. Its probably better off if the bit pattern for NULL is the same as the bit pattern for the integer 0. I know that I have written code in the past that makes incorrect assumptions about NULL pointers, (when I run across it now, I fix it, but I'd rather not go looking for the results of past sins.) and there is enough code from others that does the same. -- Andrew Langmead