[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Triggers status?



On Thu, Oct 25, 2007 at 09:09:23AM +0100, Peter Karlsson wrote:
> Ian Jackson:
> 
> > This isn't a matter of preference, I'm afraid.  I reverted this
> > because the change was wrong. NULL is incorrect in that context (a
> > stdarg function expecting a char*), because it may be #define'd to 0.
> 
> NULL will always do, no matter if it is defined to "0" or "(void *) 0".
> 
> Try this:
> 
>   char *p = 1; // produces compiler warning
>   char *p = 0; // does not

The problem is with stdarg calls, like Ian said.  If you do
   printf("%p", 0);
or
   printf("%p", (void *)0);

You pass something different to printf().  In the first case you pass an
integer, in the second case you pass a pointer.  If sizeof(int) !=
sizeof(void *) you clearly have a problem.  The promotion rules does not
change it from interger to a longer type.  So if you want to pass a NULL
pointer you need to explicitly cast it.

Try this on for instance amd64:
printf("%p %p %p %p %p %p %p %p\n", 1, (void *)2, 3, 4, 5, 6, 7, 8);

The result is:
0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x7fff00000008

Or:
printf("%p %p %p %p %p %p %p %p %p %p\n", 1, (void *)2, 3, 4, 5, 6, 7, 8, 9, 10);
gives:
0x1 0x2 0x3 0x4 0x5 0x6 0x2b6c00000007 0x8 0x9 0x7fff0000000a

and:
printf("%p %p %p %p %p %p %p %p %p %p\n", 1, (void *)2, 3, 4, 5, 6, 7, 8, 9, (void *)10);
0x1 0x2 0x3 0x4 0x5 0x6 0x2ba900000007 0x8 0x9 0xa


The reason this works for a few without paramters has to do with calling
convention and implementation details.  With other words, it's pure
luck.  Just like it's pure luck that casting the 10th parameter to a void * 
gets you the right value again, because amd64 does stdarg different than most
arches in Debian.

You could also argue that since it's passed as an interger instead of a
pointer it might actually pass the wrong value, even in case sizeof(int)
== sizeof(void *).  A NULL pointer does not need to be represented as
all bits 0, but you can still write it as 0.

Anyway, for those who care, I prefer to write it as (void *)NULL.


Kurt



Reply to: