Googy said:
Hi friends!!
As we know that the input parameters in a function is fixed when the
function is defined but how does printf processes variable number of
input arguments ?
For example:
1. printf("Hey! how are you"); /*No. of arguments = 1*/
2. printf("Sum of %d and %d is %d",a,b,c"); /* No. of arguments = 4*/
I know it uses three macros va_start, va_arg, va_list ; but i don't
know how the stuff actually works...
Please explain.
Thanks in advance!!
Gaurav
Easy one first.
If you take one vanilla implementation, like 32 bit windows
or 32 bit linux you have:
o A pointer to the start of the stack area where parameters are pushed
The macro va_start sets the va_list variable to point of the start
of the argument stack area.
o Then, each time you take out something from the va_list you increase
that pointer by sizeof(type) with appropiate rounding to a word size.
More difficult one:
Under the windows 64 operating system the first 4 arguments are
passed with the registers, no pushing into the stack. The above schema
would not work at all. Then, the va_list must point to a structure
where you have several pointers. One to the stack area where the
registers are saved, to pull possible values from them, then, a
pointer to the stack area where the arguments 5th to N are stored.
Interesting bugs can happen when you forget the 32 bytes of stack
offset that windows reserves, and the fact that floating point
registers are pulled from the SSE registers and integer/pointer
arguments are pulled from the integer registers.
Phew... took me a while.
HELL:
Absolute hell is of course, linux 64 bits. In that system, up
to 8 integer arguments can be passed in the integer registers,
up to 8 arguments can be passed in the floating point registers,
and the rest is passed in the stack... So, instead of just
looking at a single register save area you have to look to 2 of them
and maintain pointers to each one. Each pointer is incremented
independently, to the contrary of windows.
This is of course much more efficient schema than windows, but it is
pure hell for the compiler writer. Took me like a month of bug
after bug after bug.
For instance, structures are normally always passed in the stack, unless
they are smaller than a word...