hi,
I came across several books named "brain-friendly" and think this term
is cool, so I use it here. :)
To C beginners, I hope my explanation would help you understand.
Variable argument functions remain mysterious to me for a long time. I
don't understand those macros thus it's difficult to remember them.
By looking at the GNU version of the stdarg.h , I try to demysterfy it
and I'd like to share with you.
/// A sample C source file to demo function that has varible arguments
#include <stdarg.h>
void demo_func(fmt, ...)
{
va_list arg_ptr;
// define an argument pointer, va_list is char*, so code interpreted as
// char* arg_ptr;
va_start ( arg_ptr, fmt);
// let argument pointer points to the variable arguments passed in,
code interpreted as
// arg_ptr = (char*) ...
// obviously the above doesn't compile. but we know '...' is next
argument of fmt,
// and compiler knows how to find it. it is done by pragma
__builtin_next_arg_(fmt)
int i = va_arg(arg_ptr, int);
// get an integar from the variable arguments, assume caller agree
first argument is int.
// code interpreted as
// (arg_ptr = arg_ptr + sizeof(type), *((type*)(void*)arg_ptr -
sizeof(type)))
// what magic did above line do? To understand this, we know the comma
operator
// evaluate expression from left to right, and the value of left part
is discarded and expression evaluates to the right part.
// So evaluation of the left part only has side effects.
// Now the left part of the above line is moving the argument pointer
an offset of int
// the right part is to dereferencing the argument pointer before its
advancement to fetch an integar
float f = va_arg(arg_ptr, float);
// get a float from variable arguments
// ... get more arguments
va_end(arg_ptr);
// says to clear the buffer if we used any buffer. but actually it
doesn't nothing.
}
Note, the actually stdarg.h look more complex than explained here. If
you're not puzzled, you 'll find the header file basically do two
things, first implements all the macros (va_list, ...). second is to
provide portability. For example, the 'sizeof' is not accurate since
different platform has different paddings, so header file use lots of
ifdefs and rounding to calculate actual size.
Finally, if you find anything wrong, I'd appreciate your comments.
Frank,