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

Re: Triggers status?



Kurt Roeckx wrote:
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.

With va args, the arguments are always passed in a uniform size ( with padding as needed ), which is MAX( sizeof( void * ), sizeof( long ) ), so it doesn't make any difference.

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

Seems to accept 1 and (void *)2 as pointers just fine. What is with the 8 getting screwed up though?

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

Looks like a bug in the compiler to me. It appears to be padding out the integers to 64 bits like it should, but not zeroing the padding bits, instead leaving them as undefined values.

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: