Variable list in pre-processor define

A

Allan Bruce

Is there a way to make a pre-processor define with a variable number of
arguements? I want to have something like this:

#define DBG_WRITE(char *A, ...)
{
va_list vl;
char dbgTmpStr[1024];
va_start(vl, A);
vsprintf(dbgTmpStr, A, vl);
va_end(vl);
fprintf(gDbgFP, dbgTmpStr);
fflush(gDbgFP);
}

But this obviously doesnt compile.
At the moment I have DBG_WRITE0 for no additional params, DB_WRITE1 for 1
additional param and so on which is quite messy.
I can make a define that works for printf like this:

#define DBG_PRINTF(A) printf A;
and then I just call it like this: DBG_PRINTF(("Hello %s\n, someName));
(note the double brackets).

Is there a way I can achieve this for fprintf()?

Thanks,
Allan
 
M

Michael Mair

Allan said:
Is there a way to make a pre-processor define with a variable number of
arguements? I want to have something like this:

#define DBG_WRITE(char *A, ...)
^^^^^^
You want to have a macro, not a function.
{
va_list vl;
char dbgTmpStr[1024];
va_start(vl, A);
vsprintf(dbgTmpStr, A, vl);
va_end(vl);
fprintf(gDbgFP, dbgTmpStr);
fflush(gDbgFP);
}

But this obviously doesnt compile.
At the moment I have DBG_WRITE0 for no additional params, DB_WRITE1 for 1
additional param and so on which is quite messy.
I can make a define that works for printf like this:

#define DBG_PRINTF(A) printf A;
and then I just call it like this: DBG_PRINTF(("Hello %s\n, someName));
(note the double brackets).

Is there a way I can achieve this for fprintf()?

In C99: Yes.
#define DBG_WRITE(fmt, ...) \
{\
fprintf(gDbgFP, fmt, __VA_ARGS__);\
fflush(gDbgFP);\
}

For function like macros, one usually does
#define DBG_WRITE(fmt, ...) \
do {\
fprintf(gDbgFP, fmt, __VA_ARGS__);\
fflush(gDbgFP);\
} while (0)
which works with
if(....)
DBG_WRITE("Failure (line %d)\n",__LINE__);
else
......
(see clc FAQ)

For C89, I suggest writing a vararg function and then
calling v*printf().


Cheers
Michael
 
K

Kevin Bracey

In message <[email protected]>
"Allan Bruce said:
Is there a way to make a pre-processor define with a variable number of
arguements? I want to have something like this:

#define DBG_WRITE(char *A, ...)
{
va_list vl;
char dbgTmpStr[1024];
va_start(vl, A);
vsprintf(dbgTmpStr, A, vl);
va_end(vl);
fprintf(gDbgFP, dbgTmpStr);
fflush(gDbgFP);
}

But this obviously doesnt compile.
At the moment I have DBG_WRITE0 for no additional params, DB_WRITE1 for 1
additional param and so on which is quite messy.
I can make a define that works for printf like this:

#define DBG_PRINTF(A) printf A;
and then I just call it like this: DBG_PRINTF(("Hello %s\n, someName));
(note the double brackets).

Is there a way I can achieve this for fprintf()?

C99 adds the feature of variadic macro arguments. Even if not fully
C99-conformant, a lot of compilers will probably support at least this
feature, as it's pretty easy:

#define DBG_WRITE(...) \
do { \
fprintf(gDbgFP, __VA_ARGS__); \
fflush(gDbgFP); \
} while (0)

The trailing macro parameter(s) that go in the position of the ellipsis are
substituted into __VA_ARGS__. Unlike functions, it's legal to have the
ellipsis and no named parameters.

By the way, rather than have the fflush after every fprintf, it might be
neater to change the buffering of gDbgFP to be line-based, or make it
non-buffered, with a call to setvbuf.

I also don't understand what the temporary buffer was about in your original
example - why not vfprintf? It would also have had problems with "%"
characters - the fprintf should have been fprintf(gDbgFP, "%s", dbgTmpStr).
 
A

Allan Bruce

C99 adds the feature of variadic macro arguments. Even if not fully
C99-conformant, a lot of compilers will probably support at least this
feature, as it's pretty easy:

#define DBG_WRITE(...) \
do { \
fprintf(gDbgFP, __VA_ARGS__); \
fflush(gDbgFP); \
} while (0)

The trailing macro parameter(s) that go in the position of the ellipsis
are
substituted into __VA_ARGS__. Unlike functions, it's legal to have the
ellipsis and no named parameters.

By the way, rather than have the fflush after every fprintf, it might be
neater to change the buffering of gDbgFP to be line-based, or make it
non-buffered, with a call to setvbuf.

I also don't understand what the temporary buffer was about in your
original
example - why not vfprintf? It would also have had problems with "%"
characters - the fprintf should have been fprintf(gDbgFP, "%s",
dbgTmpStr).


Thanks for the replies - doesn't look as if Visual Studio supports this :-(
Allan
 
S

SM Ryan

# Is there a way to make a pre-processor define with a variable number of
# arguements? I want to have something like this:


#ifdef DEBUGGING
void DBG_WRITE(char *A,...) {
va_list vl;
va_start(vl, A);
vfprintf(gDbgFP, A, vl);
va_end(vl);
fflush(gDbgFP);
}
#else
#define DBG_WRITE (void)
#endif
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,159
Messages
2,570,881
Members
47,418
Latest member
NoellaXku

Latest Threads

Top