By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,814 Members | 1,671 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,814 IT Pros & Developers. It's quick & easy.

Variable list in pre-processor define

P: n/a
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
Nov 14 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a


Allan Bruce wrote:
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
--
E-Mail: Mine is a gmx dot de address.

Nov 14 '05 #2

P: n/a
In message <11*************@corp.supernews.com>
"Allan Bruce" <ab****@TAKEMEAWAY.csd.abdn.ac.uk> wrote:
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).

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #3

P: n/a
> 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
Nov 14 '05 #4

P: n/a
"Allan Bruce" <ab****@TAKEMEAWAY.csd.abdn.ac.uk> wrote:
# 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

--
SM Ryan http://www.rawbw.com/~wyrmwif/
I'm not even supposed to be here today.
Nov 14 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.