[PATCH] Fixes sentinel warnings on GCC4
Chris Shoemaker
c.shoemaker at cox.net
Mon Dec 5 18:28:00 EST 2005
On Mon, Dec 05, 2005 at 05:26:34PM -0500, Derek Atkins wrote:
> Quoting Chris Shoemaker <c.shoemaker at cox.net>:
>
> >On Mon, Dec 05, 2005 at 04:38:40PM -0500, Derek Atkins wrote:
> >>If you were on IRC you'd have more information on this.
> >>
> >>Yes, it is 64-bit only. The problem is that on some versions of gcc4
> >>stddef.h #defined NULL as (int)0 which causes a compiler warning when
> >>passing that into a char*.
> >
> >I'm no expert, and I don't actually know what gcc #defines NULL to,
> >but I don't think this is quite right. I don't think this is a gcc
> >problem. No compiler can infer the correct type for variadic
> >arguments. In a variadic argument list, a compiler *must* interpret
> >an unqualified "0" (which is probably what NULL is) as integer type.
> >Our code is just wrong for any machine where the null pointer is not a
> >32 bit zero, even if it's some (imaginary) 32-bit machine.
>
> The problem is that you cannot pass a 32-bit integer into a 64-bit adddress.
> On my system (32-bit, gcc-3.4.3) NULL is either defined as 0, (void*)0, or
> __null depending on other #ifdefs (which I didn't go examine). However
> if the callee is expecting a 64-bit pointer and you pass it a 32-bit
> integer, the compiler WILL (and SHOULD) complain. With -Werror this
> causes the build to blow out.
This is good.
>
> >>The fix (which David is working on -- which you'd know if you were in
> >>IRC) is to #define GNC_NULL ((gpointer)0) and then use that instead of
> >>NULL in these places.
> >
> >Hmm. Seems a bit heavy-handed to me, but it would work. I hope it
> >doesn't result in gratuitous use of GNC_NULL in the 99% of places
> >where NULL is fine.
>
> I think it would only be used in the particular cases where this is an
> issue. HOWEVER....
>
> >IMHO, it's better that programmers remain aware that the use of NULL
> >as a sentinel is "special". IOW, *not* hiding this behavior gives a
> >better picture of what the code actually does, which tends to make for
> >better code and better programmers in the long run. One problem I see
> >with GNC_NULL, is visibility. If it's too visible, people use it
> >gratuitously; if it's not visible enough, people forget to use it when
> >they should; How to choose? Better just to /understand/ what's going
> >on.
>
> ... we're still trying to analyze the issue and figure out what's really
> going on. I.e., there's no plan to make any changes until we understand
> the problem. David just went and tried to reproduce this on an amd64
> machine and could not reproduce it. Then we hear back that these errors
> are on a 32-bit machine.. (all this is on IRC, and all in the last
> few minutes).. So.. We're still trying to figure out what the REAL
> problem is before we consider this a gnucash bug.
>
> I agree with you that this SHOULDN'T be a problem, and we SHOULDN'T
> need to make this change.
You misunderstand me. This *is* a problem, and we *should* fix it.
Our code is just *wrong*. It's wrong on 32-bit machines and on 64-bit
machines. (Although it happens to be a benign bug anywhere ((char *)
NULL) is a 32-bit zero, which is almost everywhere.) It's just wrong
C. '0' is only equivalent to the typed null pointer in a pointer
context (that's even true when a typed null pointer is not a 32-bit
null; it's part of the language definition of a null pointer.) An
argument list to a variadic function is no different than a function
with no prototype - the arguments are NOT in pointer context.
The C-language rule is "always cast NULL when used as a sentinel to a
variadic function, otherwise you're accidentally passing integer
zero, which is wrong."
-chris
More information about the gnucash-devel
mailing list