[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

NULL and (char *) 0 (was: dpkg semi-hijack - an announcement (also, triggers))

Riku Voipio <riku.voipio@iki.fi> writes:
> On Sun, Mar 09, 2008 at 06:34:36PM +0000, Ian Jackson wrote:
>> Pierre Habouzit writes:

>>>   If you're so afraid that one of the included headers defines NULL to
>>> '0', then just assert (__builtin_types_compatible(NULL, void *))
>>> somewhere and be done with it. But please, (char *)0 is not only wrong,
>>> it's also tasteless and ugly to the eye.

>> In what way is (char*)0 wrong in these contexts ?

> According to execlp manpage:
> 	The list of arguments must be terminated by a NULL pointer,
> 	and, since these are vari‐adic functions, this pointer _must_
> 	be cast (char *) NULL.

(char *) NULL is completely equivalent to (char *) 0 in C.

Ian is entirely correct from the standpoint of C standards pedanticism.
Either 0 or NULL is a valid null pointer constant in any context in which
a pointer is expected, and in variadic functions, using NULL is not safe.
Even apart from the fact that NULL is permitted to be defined to 0, and
hence not a pointer in a variadic context, the C standard does not require
that all pointers be the same.  (void *) 0 is permitted to be a different
bit pattern than (int *) 0 and neither is required to be an all-zero bit
pattern.  In order to be entirely correct, you must cast a NULL pointer
constant passed to a variadic function to exactly the type of pointer that
the function expects, whether that be char *, int *, or something else.
Using NULL, or even always using (char *) 0 without regard for what's
expected, is not correct.

It's fairly unlikely that any of this would result in noticable bugs on
the systems to which Debian has been ported, given that gcc defines NULL
to ((void *) 0) and none of the systems on which Debian runs use different
bit patterns for null pointer constants for different types of constants
(and doing so would break a lot of code written with less detailed
attention to the standard).

Usually people don't worry about this (and make other similar assumptions,
like assuming that you can initialize a structure containing pointers with
calloc and get null pointers).  I try not to, when I remember, but given
the paucity of systems on which these assumptions break, most C code that
you see is not this careful.

This topic is a whole *section* in C FAQ, BTW.  See:


Russ Allbery (rra@debian.org)               <http://www.eyrie.org/~eagle/>

Reply to: