[PATCH] Fixes sentinel warnings on GCC4

Chris Shoemaker c.shoemaker at cox.net
Tue Dec 6 16:07:38 EST 2005


On Tue, Dec 06, 2005 at 08:46:00AM -0800, Karl Hegbloom wrote:
> On Tue, 2005-12-06 at 00:55 -0500, Chris Shoemaker wrote:
> > In the gcc ML thread where the -Wstrict-null-sentinel warning was
> > added, it was claimed that at least some versions of HPUX and Solaris
> > 2.8 on 64-bit machines #define NULL 0.
> 
> Then those system headers are wrong, 

You may prefer #define NULL ((void*)0), but #define NULL 0 is not
"wrong", if "wrong" means violating some standard.

C has always required that "0" in a pointer context represents the
null pointer constant.  (see K&R, 2ed p. 102) Furthermore, C99
clarifies that *any* integer constant expression with the value 0 is
the null pointer constant.  (This is why, e.g. "GncBudget *bgt = 0;"
is 100% portable.)  It also says the same thing about any such
constant cast to (void *).

Also, according to the standard, NULL may expand to any
implementation-defined null pointer constant.  That includes both "0"
and "(void*)0".  This is compeletely valid and useful behavior,
because any standard-compliant compiler must read both "0" (when in a
pointer context) and "(void*)0" as valid null pointer constants.

> not the code that uses NULL as a (void *)0.

(This is a separate issue, and if you care to define "wrong" as
implementation-dependent and not portable, then, yes, it is "wrong".)
Any code that _depends_ on NULL expanding to (void*)0, is depending on
something that is not guaranteed by the language.  It is *not* 100%
portable.  Look:

  int i = NULL;  // BAD IDEA!

Yes, this *works*!  IFF NULL expands to "0".  But, it's not portable
because NULL *may* expand to (void*)0.  This is *exactly* why using
"NULL" (or even "0") as a sentinel is not portable.  Portable code
*must* explicitly cast sentinels.  Don't blame me - blame Ritchie.

Remember: arguments to variadic functions are NOT in a pointer
context.  

-chris


More information about the gnucash-devel mailing list