C pointers

Programming, for all ages and all languages.
Post Reply
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

C pointers

Post by mark3094 »

Hi,

I've been trying to understand the va_arg macro source (compiler is Visual Studio 10, on 32-bit x86).
I have found source code on the net:

Code: Select all

#define va_arg(ap, t)	(*(t *) ((ap += intsizeof(t)) - intsizeof(t)))
I have tired the code, and it works, but I want to be able to understand how it works. I'm having problems figuring out why the size of the type (t), for example and integer (4) is added to ap, and then subtracted again.

Can anyone help me to understand why this is?



For reference, this is the intsizeof macro:

Code: Select all

#define intsizeof(n)	((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: C pointers

Post by Combuster »

To break it up into steps:

Round x down to a multiple of n
x - (x % n)
Now to round x up rather than down, there are n-1 cases that need correcting, all cases that are not a multiple of n already. Try a few actual numbers to see why it works:
(x + n - 1) - ((x + n - 1) % n)
if n is a power of two, binary operations can be substituted
(x + n - 1) - ((x + n - 1) & (n - 1))
removing some bits is the same as keeping the other bits:
(x + n - 1) & ~(n - 1)

now what is rounded up to what?
((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))


now for the other macro:
we want
x
that's the same as
x + n - n
which yields the same value as
x += n - n
with the only difference is that x is changed.

In other words: modify x, return the original.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: C pointers

Post by mark3094 »

Thankyou for your help.

I have a shaky understanding, so let me try explaining it back to see if I have it right.

There are two purposes to this code:
1. Return the value in the ap pointer
2. Update ap to the next value for next time it is accessed

(ap += intsizeof(t))
This updates ap to the next value for the next time the pointer is accessed, satisfying point 2

((ap += intsizeof(t)) - intsizeof(t))
This as a whole updates ap (as shown above), but subtracts the size of the current value (t) so it can return a pointer to the current data


I think I have that sorted out in my head now. Even just writing it down helps

Thanks again
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: C pointers

Post by Owen »

Note that this is completely 32-bit x86 specific. AMD64 (both MS and SystemV ABIs), PowerPC, SPARC and ARM (among others) have ABIs which require the compiler to implement varargs support using intrinsics.
Post Reply