They aren’t type-safe, but many times it is so nice to have a function takes varying numbers of arguments. The standard C printf function is a perfect example. And many of the functions I write with var args are logging functions that take a printf-style format string.
Declaring the functions
Fortunately, all you have to do is use the ellipses to represent the variable arguments. Put them after the last mandatory argument.
/* Log Functions */
void citLogPrintf (UINT32 flag, const char* format, ...);
void citLogPrintfDef (UINT32 flag, const char* format, ...);
Including headers
You need to include stdarg.h to get the macro definitions you will need.
Writing the functions
You will need to declare a variable of type va_list, usually I call it args.
Then call va_start, pass it the variable and the last mandatory argument, e.g. va_start (args, format);
Then you have two options:
- Use the va_list to pass to a function which takes a va_list as a parameter, such as vsnprintf.
- Process the arguments yourself using the provided macros.
I almost always need option #1, so I don’t have an example of #2.
Sample Code
#include <stdlib.h>
void citLogPrintf (UINT32 flag, const char* format, ...)
{
va_list args;
cit_log log;
int status;
if (((_citLogRemoteFlags | _citLogLocalFlags) & flag) != 0)
{
va_start (args, format);
vsnprintf (log.message, sizeof(log.message), format, args);
if ((_citLogLocalFlags & flag) != 0)
{
logMsg ("%s", (int) log.message, 2,3,4,5,6);
millisleep (100);
}
if ((_citLogRemoteFlags & flag) != 0)
{
/* send a log message to the CIT master */
log.message_type = CIT_LOG;
log.lid = _citLid;
status = msgSend (_citTxPort, &log, sizeof(log), 0, 0);
}
}
}
Tags: varargs, variable arguments