Date: Mon, 1 Mar 2004 15:21:45 +0100 From: Erik Trulsson <ertr1013@student.uu.se> To: Thomas David Rivers <rivers@dignus.com> Cc: mark@grondar.org Subject: Re: NULL vs 0 vs 0L bikeshed time Message-ID: <20040301142145.GA59401@falcon.midgard.homeip.net> In-Reply-To: <200403011315.i21DFvC95798@lakes.dignus.com> References: <200402291546.i1TFkZ0w070591@grimreaper.grondar.org> <200403011315.i21DFvC95798@lakes.dignus.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Mar 01, 2004 at 08:15:57AM -0500, Thomas David Rivers wrote: > > > > 1) Please restrain the need to bikeshed this one to death. I am > > sympathetic to technical arguments, but compulsive noise over > > such issues is annoying. > > > > 2) Please separate style disussion from technical discussion. > > > > I'd like to commit the following patch. It makes sure that for C > > and the kernel, NULL is a ((void *)0), and for C++, NULL is either > > (0L) or 0, with __LP64__ used to define the difference. > > > > The intent is to catch use of NULL where 0 or (0L) should be used. > > It generates extra warnings (I promise to fix these). > > > > I believe that _may_ be backwards; the C and C++ standards > speak to this, and both of them have slightly different > requirements. > > The C standard discuss the NULL constant, implying it is simply > a zero (not necessarily cast to a pointer.) > > But - I believe (and I need to check on this) that the C++ > standard requires the NULL constant to be a pointer type (so > various conversions work.) It's the other way around. In C NULL may be defined as an integer constant with value 0, or such a constant cast to (void*). In C++ it must be an integer constant. (The reason is that C++ has stricter type-checking and does *not* perform the implict conversions between void-pointers and other pointers that C does.) The patch seems to be technically correct and standards-compliant, and no correct programs should have any problems with the patch. However even as it will expose bugs in some programs, the patch will hide bugs in other programs. Such buggy programs caused a long thread earlier on how NULL should be defined which I suspect influenced the creation of this patch. The problem is that when using an unadorned NULL as an argument to a vararg function (or a non-prototyped function) there will be no automatic casting to the correct type. This means that if NULL is defined as 0, it will be passed as an integer even if the called function expects a (void*). For this reason correct programs must always cast a NULL to the correct type for such functions. (For functions with a prototype in scope, the argument will be automatically cast to the correct type.) This will cause problems if you have 64-bit pointers and 32-bit int's. This patch will make such programs work as intended and thus hide that this bug exists, thereby making it less likely that such programs are actually fixed. However, as indicated above, the patch will help flush out other bugs and as such it might be a good idea to use it. >From a stylistic point of view I think it is really ugly to have NULL defined in defined in different ways depending on language/architecture, but I guess that is a necessary evil if one is to find as many bugs as possible. On a related note, is there some particular reason for having the C++ definition depend on __LP64__ or could one not just as well define NULL as (0L) all the time there? (I.e. is there any platform FreeBSD runs on that have 32-bit longs and 64-bit pointers, or does all of them have pointers and long being the same size?) -- <Insert your favourite quote here.> Erik Trulsson ertr1013@student.uu.se
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040301142145.GA59401>