Variadic C/C++
Ξ September 27th, 2009 | → 0 Comments |
∇ Programming | ∇ C/C++, Logging, Variadic |
Did you ever wanted to create your own printf and never knew how to make your functions or methods take a variable number or arguments? Then this test if for you…
If you ever took the chance to read the manual page for printf functions, I may noticed the following definition for the this C standard variadic function (yes, thats’s how functions/methods that a variable number of arguments):
int printf(const char *format, …);
All the magic is done by that ’strange’ three points. Let’s see how one can one them. Imagine you what to implement a logging interface using the following variadic function (note: level_t is an enumerate of the available log levels):
void log(level_t level, const char *format, …);
This allows you to add log entries like:
log(FATAL, “Exiting to unknown problem.”);
log(ERROR, “Unable to open file %s.”, filename);
log(WARNING, “Falling to default configuration.”);
log(INFORMATION, “Computation at step %d : %s.”, step, description);
log(DEBUG, “Running iteration %d.”, i);
After understanding that the ’strange’ three points represent a va_list which contains the list of arguments. The way to access the contents of the three points is as follow:
{
va_list args // 1. create the list of pointers to unnamed arguments
va_start(args, format); // 2. initialize the list of pointers to arguments
// note: the second argument must be the last of fixed arguments
printf( “Level %d”, level );// 3. use printf to display the required information
while( !va_end(args) ) // 4. iterate over available arguments, until the end of the list
{
const char *str
= va_arg( args, char * ); // 5. access the argument value
// note: it is necessary to provide the type of the argument
printf( “%s\n”, str ); // 6. display the selected argument
}
va_end( args ) // 7. cleanup the argument list
}
void log(level_t level, const char *format, …)
{
va_list args;
va_start(args, format);
printf( “Level %d”, level );
vprintf( format, args ); // notice the use of vprintf
va_end( args );
}
There is also the possibility to provide the developer with variadic MACROS. See here for more details.








