#define NULL 0
Mar. 14th, 2008 12:01 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
A discussion elsewhere raised the question of null pointers and varargs functions. The issue is essentially that NULL on its own is not guaranteed to a be a null pointer, and varargs functions are one of the contexts where this may actually matter. (The comp.lang.c FAQ has a whole section on this area.)
In particular a platform with 32-bit ints and 64-bit pointers that defined NULL to 0 would be expected to pass a value of the wrong size when just NULL was used where a pointer was expected by a varargs function.
I looked at a number of platforms to see how they defined NULL and what the outcome was.
Platform | Definition of NULL |
---|---|
Solaris | 0 on 32-bit, 0L on 64-bit |
AIX | 0 |
Linux | ((void *)0) |
HPUX | 0L |
Windows | ((void *)0) |
Mac OS X | ((void *)0) |
In all cases my test program (which passed a bare NULL for printf()'s %p conversion specifier) worked fine.
For the Windows/Linux/Mac definition of ((void *)0) this is completely unsurprising.
For HPUX, long is always the same width as a pointer. The same is true on Solaris but they went for distinct definitions for 32- and 64-bit anyway, probably to remain absolutely identical to historical definitions for 32-bit builds.
AIX is the slightly surprising one. Superficially in a 64-bit build you're passing a 32-bit value where a 64-bit value is required. In practice it turns out that it always gets away with it: the code generated to store even a 32-bit 0 is:
addi r30,r0,0 std r30,184(SP)
i.e. it always stores a 64-bit 0 even if you only ask for 32 bits (std is “store double-word”, a word being 32 bits in this context.)
(no subject)
Date: 2008-03-14 01:20 pm (UTC)(Personally, I'm using xlC on AIX, last 64-bit compile being 30 minutes ago, next being (I hope) months away.)
(no subject)
Date: 2008-03-14 01:25 pm (UTC)