An answer that was deemed unhelpful
The question was not properly explained. This answer didn't answer the question that the questioner had in mind, but did answer the question that seemed to be asked. There was a gap between intention and reality.
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__) // semi-colon removed!
void foo(PCSTR fmt, ...)
{
// some other codes
// I want to call boo with VarArgs.
if (somecondition)
boo(fmt, arg1, arg2);
if (anothercondition)
boo("%x %y %z", e1, e2, e3);
if (yetanothercondition)
boo("&T99 P37 T22 9%X ZZQ", x1, y2, z3, a4, b9, c7, q99);
}
All facetiousness apart, you call a function or macro with the arguments needed to get your job done. Since you don't specify what the format should be formatted like, I've made up format strings to suit myself - they probably aren't very usable, but who knows.
Anyway, the key point is that you can call boo()
the macro with different lists of arguments, and those arguments will be conveyed to SomethingToDo()
.
An answer that was deemed more helpful
Given the clarification in the comment, then:
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
va_list args;
// I want to call boo with VarArgs.
if (somecondition)
{
va_start(args, fmt);
boo(fmt, args);
va_end(args);
}
}
However, for that to work, the underlying function needs to know how to handle a va_list
. That means you normally end up with the following code with a structure similar to the following:
void vSomethingToDo(const char *fmt, va_list args)
{
...code using vfprintf() or whatever...
}
void SomethingToDo(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vSomethingToDo(fmt, args);
va_end(args);
}
#define vboo(fmt, args) vSomethingToDo(fmt, args)
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
...other code...
if (somecondition)
{
va_list args;
va_start(args, fmt);
vboo(fmt, args);
va_end(args);
}
}
This is a 'standard pattern' for code that uses variable arguments. You can see it in standard C with: printf()
and vprintf()
; snprintf()
and vsnprintf()
; fprintf()
and vfprintf()
; and so on. One version of the function has an ellipsis in the argument list; the other version is prefixed with the letter 'v' and takes a 'va_list' in place of the ellipsis. The ellipsis code is standardized to four or five lines - more or less as shown; it creates and initializes va_list with va_start, calls the v-function, and returns the result after doing va_end.