Date: Fri, 28 Nov 2003 16:58:23 -0800 From: Marcel Moolenaar <marcel@xcllnt.net> To: standards@FreeBSD.org Subject: 64-bit NULL: a followup Message-ID: <20031129005823.GA20090@dhcp01.pn.xcllnt.net>
next in thread | raw e-mail | index | archive | help
Previously on -standards: On Mon, Oct 27, 2003 at 02:49:51PM +0100, Harti Brandt wrote: > > a question came up wether the NULL should be defined as (0L) on sparc. > (Solaris does this). Currently we define NULL as 0. On Mon, 27 Oct 2003, Erik Trulsson wrote: > > Both are perfectly good definitions of NULL. On Mon, 27 Oct 2003, Tony Finch wrote: > > No, NULL is an implementation-defined null pointer constant, not a null > pointer. The difference is that a null pointer constant is an integer > constant expression that evaluates to zero (optionally cast to void*), > and a null pointer is a null pointer constant converted to a pointer type > (which might involve changes in representation). Therefore using a bare > NULL to terminate the execl argument list is not in general legal. On ia64 I run into a problem where a caller of a function with a variable number of arguments leaves garbage in the high order 32 bits due to the fact that NULL is defined as 0, and thus has type int by default. Take the following simple example: extern int va(int, ...); int foo(void) { return (va(1, 2, 3, 4, 5, 6, 7, 8, NULL)); } The last argument has to be passed onto the stack, which gcc does as follows: : 1c: 01 61 00 84 adds r14=16,r12;; 20: 00 00 00 1c 90 11 [MII] st4 [r14]=r0 26: 40 0a 00 00 48 a0 mov r36=1 2c: 24 00 00 90 mov r37=2 30: 00 30 0d 00 00 24 [MII] mov r38=3 36: 70 22 00 00 48 00 mov r39=4 3c: 55 00 00 90 mov r40=5 40: 00 48 19 00 00 24 [MII] mov r41=6 46: a0 3a 00 00 48 60 mov r42=7 4c: 85 00 00 90 mov r43=8 50: 1c 00 00 00 01 00 [MFB] nop.m 0x0 56: 00 00 00 02 00 00 nop.f 0x0 5c: 08 00 00 50 br.call.sptk.many b0=50 <foo+0x50> : Notice the "st4". If NULL was defined as 0L, this would look like: : 1c: 01 61 00 84 adds r14=16,r12;; 20: 00 00 00 1c 98 11 [MII] st8 [r14]=r0 26: 40 0a 00 00 48 a0 mov r36=1 : Notice the "st8". Since NULL is a pointer constant, programmers do (implicitly) expect it to have the same width as a pointer type and thus do not cast it to a pointer type or an integer type that has a width larger or equal to a pointer type. So, the bottomline is that we currently do have third-party code that fails to run on ia64 (and possibly other 64-bit platforms) due to the fact that NULL is defined as 0. Since Erik thinks 0 and 0L are both perfectly good definitions for NULL and Tony emphasizes that NULL is an integer expression, I think we should change the definition of NULL to 0L to improve portability to FreeBSD/LP64. It will definitely fix known breakages on ia64. Thoughts? -- Marcel Moolenaar USPA: A-39004 marcel@xcllnt.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031129005823.GA20090>