As arguments are passed on the stack, the va_ functions (which are implemented most of the time as macros) simply manipulate the private stack pointer. This private stack pointer is stored from the argument passed to va_start , and then va_arg "issues" the arguments from the "stack" when it iterates over the parameters.
Suppose you call the max function with three parameters, for example:
max(a, b, c);
Inside the max function, the stack basically looks like this:
+ ----- +
| c |
| b |
| a |
| ret |
SP -> + ----- +
SP is a real pointer to the stack, and itβs not really a , b and c that are on the stack, but their values. ret is the return address where to go to the function.
That va_start(ap, n) does takes the address of the argument ( n in the function prototype), and the position of the next argument is calculated from it, so we get a new pointer to the private stack:
+ ----- +
| c |
ap -> | b |
| a |
| ret |
SP -> + ----- +
When you use va_arg(ap, int) , it returns what the private stack pointer points to, and then pops it up, changing the private stack pointer to now point to the next argument. The stack now looks like this:
+ ----- +
ap -> | c |
| b |
| a |
| ret |
SP -> + ----- +
This description, of course, is simplified, but shows the principle.
Some programmer dude Sep 11 '12 at 14:13 2012-09-11 14:13
source share