From: robwah@auto-trol.UUCP (Robert Wahl) Newsgroups: comp.lang.c,comp.unix.wizards,alt.sources,comp.sources.d,misc.misc Subject: Re: #define DEBUG... (using printf for debugging) Message-ID: <1104@auto-trol.UUCP> Date: 7 May 90 22:00:03 GMT William Silver writes: >Is there a way to define Debug so that Debug(x, y, z,...) can optionally >either do nothing or generate fprintf(stderr, x, y, z,...) with an >arbitrary number of arguments? Crawford's method still requires >specific mention of stderr in each debug line. Consider the basic setup which is required to use a variable argument list in a macro. The list must be used as the argument list of a function call, and no other arguments can be added. However, that function need not be printf: #ifdef DEBUG #define DPRINTF(list) (dprintf list) #else #define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */ #endif DPRINTF ((fmtstr, arg1, arg2, arg3)); Writing "dprintf" is left as an exercise for the reader. Using assembly language, it may be an easy thing to prepend stderr to the variable argument list and then call "fprintf". Most likely, though, you will have to parse the format string for the number and type of arguments in order to set up the call to "fprintf". If so, you might as well do it all in C (which at least is portable), and do your output in stages. Here's a simply coded, but dreadfully hacky solution: temporarily replace stdout with stderr, then use printf as suggested before. This is inherently non-portable, inefficient, risky and generates lots of code. #ifdef DEBUG static FILE dprintf_stdout; static int dprintf_retval; #define DPRINTF(list) (dprintf_stdout = *stdout, *stdout = *stderr, \ dprintf_retval = printf list, *stdout = dprintf_stdout), dprintf_retval) #else #define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */ #endif If you do use this method, forget that you heard of it from me. Perhaps the best solution is just to use fixed argument lists; after all, how many values do you typically output in one debug statement? #ifdef DEBUG #define Debug0(fmt) (fprintf (stderr, fmt)) #define Debug1(fmt,val1) (fprintf (stderr, fmt, val1)) #define Debug2(fmt,val1,val2) (fprintf (stderr, fmt, val1, val2)) ... #else #define Debug0(fmt) (1) #define Debug1(fmt,val1) (1) #define Debug2(fmt,val1,val2) (1) ... #endif Debug3 ("Name is %s, value is %d (0x%x)\n", name, val, val); or Debug1 ("Name is %s, ", name); /* Note lack of newline in format string */ Debug2 ("value is %d (0x%x)\n", val, val); -- Rob Wahl =:-> {robwah@auto-trol.com | ...!ncar!ico!auto-trol|robwah}