C debug printf with fflush [duplicate] - c

Trying to create a macro which can be used for print debug messages when DEBUG is defined, like the following pseudo code:
#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)
How is this accomplished with a macro?

If you use a C99 or later compiler
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
It assumes you are using C99 (the variable argument list notation is not supported in earlier versions). The do { ... } while (0) idiom ensures that the code acts like a statement (function call). The unconditional use of the code ensures that the compiler always checks that your debug code is valid — but the optimizer will remove the code when DEBUG is 0.
If you want to work with #ifdef DEBUG, then change the test condition:
#ifdef DEBUG
#define DEBUG_TEST 1
#else
#define DEBUG_TEST 0
#endif
And then use DEBUG_TEST where I used DEBUG.
If you insist on a string literal for the format string (probably a good idea anyway), you can also introduce things like __FILE__, __LINE__ and __func__ into the output, which can improve the diagnostics:
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
__LINE__, __func__, __VA_ARGS__); } while (0)
This relies on string concatenation to create a bigger format string than the programmer writes.
If you use a C89 compiler
If you are stuck with C89 and no useful compiler extension, then there isn't a particularly clean way to handle it. The technique I used to use was:
#define TRACE(x) do { if (DEBUG) dbg_printf x; } while (0)
And then, in the code, write:
TRACE(("message %d\n", var));
The double-parentheses are crucial — and are why you have the funny notation in the macro expansion. As before, the compiler always checks the code for syntactic validity (which is good) but the optimizer only invokes the printing function if the DEBUG macro evaluates to non-zero.
This does require a support function — dbg_printf() in the example — to handle things like 'stderr'. It requires you to know how to write varargs functions, but that isn't hard:
#include <stdarg.h>
#include <stdio.h>
void dbg_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
You can also use this technique in C99, of course, but the __VA_ARGS__ technique is neater because it uses regular function notation, not the double-parentheses hack.
Why is it crucial that the compiler always see the debug code?
[Rehashing comments made to another answer.]
One central idea behind both the C99 and C89 implementations above is that the compiler proper always sees the debugging printf-like statements. This is important for long-term code — code that will last a decade or two.
Suppose a piece of code has been mostly dormant (stable) for a number of years, but now needs to be changed. You re-enable debugging trace - but it is frustrating to have to debug the debugging (tracing) code because it refers to variables that have been renamed or retyped, during the years of stable maintenance. If the compiler (post pre-processor) always sees the print statement, it ensures that any surrounding changes have not invalidated the diagnostics. If the compiler does not see the print statement, it cannot protect you against your own carelessness (or the carelessness of your colleagues or collaborators). See 'The Practice of Programming' by Kernighan and Pike, especially Chapter 8 (see also Wikipedia on TPOP).
This is 'been there, done that' experience — I used essentially the technique described in other answers where the non-debug build does not see the printf-like statements for a number of years (more than a decade). But I came across the advice in TPOP (see my previous comment), and then did enable some debugging code after a number of years, and ran into problems of changed context breaking the debugging. Several times, having the printing always validated has saved me from later problems.
I use NDEBUG to control assertions only, and a separate macro (usually DEBUG) to control whether debug tracing is built into the program. Even when the debug tracing is built in, I frequently do not want debug output to appear unconditionally, so I have mechanism to control whether the output appears (debug levels, and instead of calling fprintf() directly, I call a debug print function that only conditionally prints so the same build of the code can print or not print based on program options). I also have a 'multiple-subsystem' version of the code for bigger programs, so that I can have different sections of the program producing different amounts of trace - under runtime control.
I am advocating that for all builds, the compiler should see the diagnostic statements; however, the compiler won't generate any code for the debugging trace statements unless debug is enabled. Basically, it means that all of your code is checked by the compiler every time you compile - whether for release or debugging. This is a good thing!
debug.h - version 1.2 (1990-05-01)
/*
#(#)File: $RCSfile: debug.h,v $
#(#)Version: $Revision: 1.2 $
#(#)Last changed: $Date: 1990/05/01 12:55:39 $
#(#)Purpose: Definitions for the debugging system
#(#)Author: J Leffler
*/
#ifndef DEBUG_H
#define DEBUG_H
/* -- Macro Definitions */
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x)
#endif /* DEBUG */
/* -- Declarations */
#ifdef DEBUG
extern int debug;
#endif
#endif /* DEBUG_H */
debug.h - version 3.6 (2008-02-11)
/*
#(#)File: $RCSfile: debug.h,v $
#(#)Version: $Revision: 3.6 $
#(#)Last changed: $Date: 2008/02/11 06:46:37 $
#(#)Purpose: Definitions for the debugging system
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 1990-93,1997-99,2003,2005,2008
#(#)Product: :PRODUCT:
*/
#ifndef DEBUG_H
#define DEBUG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
/*
** Usage: TRACE((level, fmt, ...))
** "level" is the debugging level which must be operational for the output
** to appear. "fmt" is a printf format string. "..." is whatever extra
** arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike.
*/
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x) do { if (0) db_print x; } while (0)
#endif /* DEBUG */
#ifndef lint
#ifdef DEBUG
/* This string can't be made extern - multiple definition in general */
static const char jlss_id_debug_enabled[] = "#(#)*** DEBUG ***";
#endif /* DEBUG */
#ifdef MAIN_PROGRAM
const char jlss_id_debug_h[] = "#(#)$Id: debug.h,v 3.6 2008/02/11 06:46:37 jleffler Exp $";
#endif /* MAIN_PROGRAM */
#endif /* lint */
#include <stdio.h>
extern int db_getdebug(void);
extern int db_newindent(void);
extern int db_oldindent(void);
extern int db_setdebug(int level);
extern int db_setindent(int i);
extern void db_print(int level, const char *fmt,...);
extern void db_setfilename(const char *fn);
extern void db_setfileptr(FILE *fp);
extern FILE *db_getfileptr(void);
/* Semi-private function */
extern const char *db_indent(void);
/**************************************\
** MULTIPLE DEBUGGING SUBSYSTEMS CODE **
\**************************************/
/*
** Usage: MDTRACE((subsys, level, fmt, ...))
** "subsys" is the debugging system to which this statement belongs.
** The significance of the subsystems is determined by the programmer,
** except that the functions such as db_print refer to subsystem 0.
** "level" is the debugging level which must be operational for the
** output to appear. "fmt" is a printf format string. "..." is
** whatever extra arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
*/
#ifdef DEBUG
#define MDTRACE(x) db_mdprint x
#else
#define MDTRACE(x) do { if (0) db_mdprint x; } while (0)
#endif /* DEBUG */
extern int db_mdgetdebug(int subsys);
extern int db_mdparsearg(char *arg);
extern int db_mdsetdebug(int subsys, int level);
extern void db_mdprint(int subsys, int level, const char *fmt,...);
extern void db_mdsubsysnames(char const * const *names);
#endif /* DEBUG_H */
Single argument variant for C99 or later
Kyle Brandt asked:
Anyway to do this so debug_print still works even if there are no arguments? For example:
debug_print("Foo");
There's one simple, old-fashioned hack:
debug_print("%s\n", "Foo");
The GCC-only solution shown below also provides support for that.
However, you can do it with the straight C99 system by using:
#define debug_print(...) \
do { if (DEBUG) fprintf(stderr, __VA_ARGS__); } while (0)
Compared to the first version, you lose the limited checking that requires the 'fmt' argument, which means that someone could try to call 'debug_print()' with no arguments (but the trailing comma in the argument list to fprintf() would fail to compile). Whether the loss of checking is a problem at all is debatable.
GCC-specific technique for a single argument
Some compilers may offer extensions for other ways of handling variable-length argument lists in macros. Specifically, as first noted in the comments by Hugo Ideler, GCC allows you to omit the comma that would normally appear after the last 'fixed' argument to the macro. It also allows you to use ##__VA_ARGS__ in the macro replacement text, which deletes the comma preceding the notation if, but only if, the previous token is a comma:
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0)
This solution retains the benefit of requiring the format argument while accepting optional arguments after the format.
This technique is also supported by Clang for GCC compatibility.
Why the do-while loop?
What's the purpose of the do while here?
You want to be able to use the macro so it looks like a function call, which means it will be followed by a semi-colon. Therefore, you have to package the macro body to suit. If you use an if statement without the surrounding do { ... } while (0), you will have:
/* BAD - BAD - BAD */
#define debug_print(...) \
if (DEBUG) fprintf(stderr, __VA_ARGS__)
Now, suppose you write:
if (x > y)
debug_print("x (%d) > y (%d)\n", x, y);
else
do_something_useful(x, y);
Unfortunately, that indentation doesn't reflect the actual control of flow, because the preprocessor produces code equivalent to this (indented and braces added to emphasize the actual meaning):
if (x > y)
{
if (DEBUG)
fprintf(stderr, "x (%d) > y (%d)\n", x, y);
else
do_something_useful(x, y);
}
The next attempt at the macro might be:
/* BAD - BAD - BAD */
#define debug_print(...) \
if (DEBUG) { fprintf(stderr, __VA_ARGS__); }
And the same code fragment now produces:
if (x > y)
if (DEBUG)
{
fprintf(stderr, "x (%d) > y (%d)\n", x, y);
}
; // Null statement from semi-colon after macro
else
do_something_useful(x, y);
And the else is now a syntax error. The do { ... } while(0) loop avoids both these problems.
There's one other way of writing the macro which might work:
/* BAD - BAD - BAD */
#define debug_print(...) \
((void)((DEBUG) ? fprintf(stderr, __VA_ARGS__) : 0))
This leaves the program fragment shown as valid. The (void) cast prevents it being used in contexts where a value is required — but it could be used as the left operand of a comma operator where the do { ... } while (0) version cannot. If you think you should be able to embed debug code into such expressions, you might prefer this. If you prefer to require the debug print to act as a full statement, then the do { ... } while (0) version is better. Note that if the body of the macro involved any semi-colons (roughly speaking), then you can only use the do { ... } while(0) notation. It always works; the expression statement mechanism can be more difficult to apply. You might also get warnings from the compiler with the expression form that you'd prefer to avoid; it will depend on the compiler and the flags you use.
TPOP was previously at http://plan9.bell-labs.com/cm/cs/tpop and http://cm.bell-labs.com/cm/cs/tpop but both are now (2015-08-10) broken.
Code in GitHub
If you're curious, you can look at this code in GitHub in my SOQ (Stack
Overflow Questions) repository as files debug.c, debug.h and mddebug.c in the
src/libsoq
sub-directory.

I use something like this:
#ifdef DEBUG
#define D if(1)
#else
#define D if(0)
#endif
Than I just use D as a prefix:
D printf("x=%0.3f\n",x);
Compiler sees the debug code, there is no comma problem and it works everywhere. Also it works when printf is not enough, say when you must dump an array or calculate some diagnosing value that is redundant to the program itself.
EDIT: Ok, it might generate a problem when there is else somewhere near that can be intercepted by this injected if. This is a version that goes over it:
#ifdef DEBUG
#define D
#else
#define D for(;0;)
#endif

For a portable (ISO C90) implementation, you could use double parentheses, like this;
#include <stdio.h>
#include <stdarg.h>
#ifndef NDEBUG
# define debug_print(msg) stderr_printf msg
#else
# define debug_print(msg) (void)0
#endif
void
stderr_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int
main(int argc, char *argv[])
{
debug_print(("argv[0] is %s, argc is %d\n", argv[0], argc));
return 0;
}
or (hackish, wouldn't recommend it)
#include <stdio.h>
#define _ ,
#ifndef NDEBUG
# define debug_print(msg) fprintf(stderr, msg)
#else
# define debug_print(msg) (void)0
#endif
int
main(int argc, char *argv[])
{
debug_print("argv[0] is %s, argc is %d"_ argv[0] _ argc);
return 0;
}

Here's the version I use:
#ifdef NDEBUG
#define Dprintf(FORMAT, ...) ((void)0)
#define Dputs(MSG) ((void)0)
#else
#define Dprintf(FORMAT, ...) \
fprintf(stderr, "%s() in %s, line %i: " FORMAT "\n", \
__func__, __FILE__, __LINE__, __VA_ARGS__)
#define Dputs(MSG) Dprintf("%s", MSG)
#endif

I would do something like
#ifdef DEBUG
#define debug_print(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#else
#define debug_print(fmt, ...) do {} while (0)
#endif
I think this is cleaner.

According to http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html,
there should be a ## before __VA_ARGS__.
Otherwise, a macro #define dbg_print(format, ...) printf(format, __VA_ARGS__) will not compile the following example: dbg_print("hello world");.

#define debug_print(FMT, ARGS...) do { \
if (DEBUG) \
fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
} while (0)

This is what I use:
#if DBG
#include <stdio.h>
#define DBGPRINT printf
#else
#define DBGPRINT(...) /**/
#endif
It has the nice benefit to handle printf properly, even without additional arguments. In case DBG ==0, even the dumbest compiler gets nothing to chew upon, so no code is generated.

So, when using gcc, I like:
#define DBGI(expr) ({int g2rE3=expr; fprintf(stderr, "%s:%d:%s(): ""%s->%i\n", __FILE__, __LINE__, __func__, #expr, g2rE3); g2rE3;})
Because it can be inserted into code.
Suppose you're trying to debug
printf("%i\n", (1*2*3*4*5*6));
720
Then you can change it to:
printf("%i\n", DBGI(1*2*3*4*5*6));
hello.c:86:main(): 1*2*3*4*5*6->720
720
And you can get an analysis of what expression was evaluated to what.
It's protected against the double-evaluation problem, but the absence of gensyms does leave it open to name-collisions.
However it does nest:
DBGI(printf("%i\n", DBGI(1*2*3*4*5*6)));
hello.c:86:main(): 1*2*3*4*5*6->720
720
hello.c:86:main(): printf("%i\n", DBGI(1*2*3*4*5*6))->4
So I think that as long as you avoid using g2rE3 as a variable name, you'll be OK.
Certainly I've found it (and allied versions for strings, and versions for debug levels etc) invaluable.

My favourite of the below is var_dump, which when called as:
var_dump("%d", count);
produces output like:
patch.c:150:main(): count = 0
Credit to #"Jonathan Leffler". All are C89-happy:
Code
#define DEBUG 1
#include <stdarg.h>
#include <stdio.h>
void debug_vprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
/* Call as: (DOUBLE PARENTHESES ARE MANDATORY) */
/* var_debug(("outfd = %d, somefailed = %d\n", outfd, somefailed)); */
#define var_debug(x) do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): ", \
__FILE__, __LINE__, __func__); debug_vprintf x; }} while (0)
/* var_dump("%s" variable_name); */
#define var_dump(fmt, var) do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): ", \
__FILE__, __LINE__, __func__); debug_vprintf ("%s = " fmt, #var, var); }} while (0)
#define DEBUG_HERE do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): HERE\n", \
__FILE__, __LINE__, __func__); }} while (0)

I've been stewing on how to do this for years, and finally come up with a solution. However, I didn't know that there were other solutions here already. First, at difference with Leffler's answer, I don't see his argument that debug prints should always be compiled. I'd rather not have tons of unneeded code executing in my project, when not needed, in cases where I need to test and they might not be getting optimized out.
Not compiling every time might sound worse than it is in actual practice. You do wind up with debug prints that don't compile sometimes, but it's not so hard to compile and test them before finalizing a project. With this system, if you are using three levels of debugs, just put it on debug message level three, fix your compile errors and check for any others before you finalize yer code. (Since of course, debug statements compiling are no guarantee that they are still working as intended.)
My solution provides for levels of debug detail also; and if you set it to the highest level, they all compile. If you've been using a high debug detail level recently, they all were able to compile at that time. Final updates should be pretty easy. I've never needed more than three levels, but Jonathan says he's used nine. This method (like Leffler's) can be extended to any number of levels. The usage of my method may be simpler; requiring just two statements when used in your code. I am, however, coding the CLOSE macro too - although it doesn't do anything. It might if I were sending to a file.
Against the cost the extra step of testing them to see that they will compile before delivery, is that
You must trust them to get optimized out, which admittedly SHOULD happen if you have a sufficient optimization level.
Furthermore, they probably won't if you make a release compile with optimization turned off for testing purposes (which is admittedly rare); and they almost certainly won't at all during debug - thereby executing dozens or hundreds of "if (DEBUG)" statements at runtime; thus slowing execution (which is my principle objection) and less importantly, increasing your executable or dll size; and hence execution and compile times. Jonathan, however, informs me his method can be made to also not compile statements at all.
Branches are actually relatively pretty costly in modern pre-fetching processors. Maybe not a big deal if your app is not a time-critical one; but if performance is an issue, then, yes, a big enough deal that I'd prefer to opt for somewhat faster-executing debug code (and possibly faster release, in rare cases, as noted).
So, what I wanted is a debug print macro that does not compile if it is not to be printed, but does if it is. I also wanted levels of debugging, so that, e.g. if I wanted performance-crucial parts of the code not to print at some times, but to print at others, I could set a debug level, and have extra debug prints kick in. I came across a way to implement debug levels that determined if the print was even compiled or not. I achieved it this way:
DebugLog.h:
// FILE: DebugLog.h
// REMARKS: This is a generic pair of files useful for debugging. It provides three levels of
// debug logging, currently; in addition to disabling it. Level 3 is the most information.
// Levels 2 and 1 have progressively more. Thus, you can write:
// DEBUGLOG_LOG(1, "a number=%d", 7);
// and it will be seen if DEBUG is anything other than undefined or zero. If you write
// DEBUGLOG_LOG(3, "another number=%d", 15);
// it will only be seen if DEBUG is 3. When not being displayed, these routines compile
// to NOTHING. I reject the argument that debug code needs to always be compiled so as to
// keep it current. I would rather have a leaner and faster app, and just not be lazy, and
// maintain debugs as needed. I don't know if this works with the C preprocessor or not,
// but the rest of the code is fully C compliant also if it is.
#define DEBUG 1
#ifdef DEBUG
#define DEBUGLOG_INIT(filename) debuglog_init(filename)
#else
#define debuglog_init(...)
#endif
#ifdef DEBUG
#define DEBUGLOG_CLOSE debuglog_close
#else
#define debuglog_close(...)
#endif
#define DEBUGLOG_LOG(level, fmt, ...) DEBUGLOG_LOG ## level (fmt, ##__VA_ARGS__)
#if DEBUG == 0
#define DEBUGLOG_LOG0(...)
#endif
#if DEBUG >= 1
#define DEBUGLOG_LOG1(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG1(...)
#endif
#if DEBUG >= 2
#define DEBUGLOG_LOG2(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG2(...)
#endif
#if DEBUG == 3
#define DEBUGLOG_LOG3(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG3(...)
#endif
void debuglog_init(char *filename);
void debuglog_close(void);
void debuglog_log(char* format, ...);
DebugLog.cpp:
// FILE: DebugLog.h
// REMARKS: This is a generic pair of files useful for debugging. It provides three levels of
// debug logging, currently; in addition to disabling it. See DebugLog.h's remarks for more
// info.
#include <stdio.h>
#include <stdarg.h>
#include "DebugLog.h"
FILE *hndl;
char *savedFilename;
void debuglog_init(char *filename)
{
savedFilename = filename;
hndl = fopen(savedFilename, "wt");
fclose(hndl);
}
void debuglog_close(void)
{
//fclose(hndl);
}
void debuglog_log(char* format, ...)
{
hndl = fopen(savedFilename,"at");
va_list argptr;
va_start(argptr, format);
vfprintf(hndl, format, argptr);
va_end(argptr);
fputc('\n',hndl);
fclose(hndl);
}
Using the macros
To use it, just do:
DEBUGLOG_INIT("afile.log");
To write to the log file, just do:
DEBUGLOG_LOG(1, "the value is: %d", anint);
To close it, you do:
DEBUGLOG_CLOSE();
although currently this isn't even necessary, technically speaking, as it does nothing. I'm still using the CLOSE right now, however, in case I change my mind about how it works, and want to leave the file open between logging statements.
Then, when you want to turn on debug printing, just edit the first #define in the header file to say, e.g.
#define DEBUG 1
To have logging statements compile to nothing, do
#define DEBUG 0
If you need info from a frequently executed piece of code (i.e. a high level of detail), you may want to write:
DEBUGLOG_LOG(3, "the value is: %d", anint);
If you define DEBUG to be 3, logging levels 1, 2 & 3 compile. If you set it to 2, you get logging levels 1 & 2. If you set it to 1, you only get logging level 1 statements.
As to the do-while loop, since this evaluates to either a single function or nothing, instead of an if statement, the loop is not needed. OK, castigate me for using C instead of C++ IO (and Qt's QString::arg() is a safer way of formatting variables when in Qt, too — it's pretty slick, but takes more code and the formatting documentation isn't as organized as it might be - but still I've found cases where its preferable), but you can put whatever code in the .cpp file you want. It also might be a class, but then you would need to instantiate it and keep up with it, or do a new() and store it. This way, you just drop the #include, init and optionally close statements into your source, and you are ready to begin using it. It would make a fine class, however, if you are so inclined.
I'd previously seen a lot of solutions, but none suited my criteria as well as this one.
It can be extended to do as many levels as you like.
It compiles to nothing if not printing.
It centralizes IO in one easy-to-edit place.
It's flexible, using printf formatting.
Again, it does not slow down debug runs, whereas always-compiling debug prints are always executed in debug mode. If you are doing computer science, and not easier to write information processing, you may find yourself running a CPU-consuming simulator, to see e.g. where the debugger stops it with an index out of range for a vector. These run extra-slowly in debug mode already. The mandatory execution of hundreds of debug prints will necessarily slow such runs down even further. For me, such runs are not uncommon.
Not terribly significant, but in addition:
It requires no hack to print without arguments (e.g. DEBUGLOG_LOG(3, "got here!");); thus allowing you to use, e.g. Qt's safer .arg() formatting. It works on MSVC, and thus, probably gcc. It uses ## in the #defines, which is non-standard, as Leffler points out, but is widely supported. (You can recode it not to use ## if necessary, but you will have to use a hack such as he provides.)
Warning: If you forget to provide the logging level argument, MSVC unhelpfully claims the identifier is not defined.
You might want to use a preprocessor symbol name other than DEBUG, as some source also defines that symbol (eg. progs using ./configure commands to prepare for building). It seemed natural to me when I developed it. I developed it in an application where the DLL is being used by something else, and it's more convent to send log prints to a file; but changing it to vprintf() would work fine, too.
I hope this saves many of you grief about figuring out the best way to do debug logging; or shows you one you might prefer. I've half-heartedly been trying to figure this one out for decades. Works in MSVC 2012 & 2015, and thus probably on gcc; as well as probably working on many others, but I haven't tested it on them.
I mean to make a streaming version of this one day, too.
Note: Thanks go to Leffler, who has cordially helped me format my message better for StackOverflow.

#define PRINT_LOG(str_format, ...) { \
time_t curtime=time (NULL); \
struct tm *ltm = localtime (&curtime); \
printf("[%d-%02d-%02d %02d:%02d:%02d] " str_format, \
ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, \
ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ##__VA_ARGS__); \
}
PRINT_LOG("[%d] Serving client, str=%s, number=%d\n", getpid(), "my str", 10);

I believe this variation of the theme gives debug categories without the need to have a separate macro name per category.
I used this variation in an Arduino project where program space is limited to 32K and dynamic memory is limited to 2K. The addition of debug statements and trace debug strings quickly uses up space. So it is essential to be able to limit the debug trace that is included at compile time to the minimum necessary each time the code is built.
debug.h
#ifndef DEBUG_H
#define DEBUG_H
#define PRINT(DEBUG_CATEGORY, VALUE) do { if (DEBUG_CATEGORY & DEBUG_MASK) Serial.print(VALUE);} while (0);
#endif
calling .cpp file
#define DEBUG_MASK 0x06
#include "Debug.h"
...
PRINT(4, "Time out error,\t");
...

If you don't care that the output goes to stdout, you can use this:
int doDebug = DEBUG; // Where DEBUG may be supplied in compiler command
#define trace if (doDebug) printf
trace("whatever %d, %i\n", arg1, arg2);

Related

Remove debug strings from release build [duplicate]

Trying to create a macro which can be used for print debug messages when DEBUG is defined, like the following pseudo code:
#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)
How is this accomplished with a macro?
If you use a C99 or later compiler
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
It assumes you are using C99 (the variable argument list notation is not supported in earlier versions). The do { ... } while (0) idiom ensures that the code acts like a statement (function call). The unconditional use of the code ensures that the compiler always checks that your debug code is valid — but the optimizer will remove the code when DEBUG is 0.
If you want to work with #ifdef DEBUG, then change the test condition:
#ifdef DEBUG
#define DEBUG_TEST 1
#else
#define DEBUG_TEST 0
#endif
And then use DEBUG_TEST where I used DEBUG.
If you insist on a string literal for the format string (probably a good idea anyway), you can also introduce things like __FILE__, __LINE__ and __func__ into the output, which can improve the diagnostics:
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
__LINE__, __func__, __VA_ARGS__); } while (0)
This relies on string concatenation to create a bigger format string than the programmer writes.
If you use a C89 compiler
If you are stuck with C89 and no useful compiler extension, then there isn't a particularly clean way to handle it. The technique I used to use was:
#define TRACE(x) do { if (DEBUG) dbg_printf x; } while (0)
And then, in the code, write:
TRACE(("message %d\n", var));
The double-parentheses are crucial — and are why you have the funny notation in the macro expansion. As before, the compiler always checks the code for syntactic validity (which is good) but the optimizer only invokes the printing function if the DEBUG macro evaluates to non-zero.
This does require a support function — dbg_printf() in the example — to handle things like 'stderr'. It requires you to know how to write varargs functions, but that isn't hard:
#include <stdarg.h>
#include <stdio.h>
void dbg_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
You can also use this technique in C99, of course, but the __VA_ARGS__ technique is neater because it uses regular function notation, not the double-parentheses hack.
Why is it crucial that the compiler always see the debug code?
[Rehashing comments made to another answer.]
One central idea behind both the C99 and C89 implementations above is that the compiler proper always sees the debugging printf-like statements. This is important for long-term code — code that will last a decade or two.
Suppose a piece of code has been mostly dormant (stable) for a number of years, but now needs to be changed. You re-enable debugging trace - but it is frustrating to have to debug the debugging (tracing) code because it refers to variables that have been renamed or retyped, during the years of stable maintenance. If the compiler (post pre-processor) always sees the print statement, it ensures that any surrounding changes have not invalidated the diagnostics. If the compiler does not see the print statement, it cannot protect you against your own carelessness (or the carelessness of your colleagues or collaborators). See 'The Practice of Programming' by Kernighan and Pike, especially Chapter 8 (see also Wikipedia on TPOP).
This is 'been there, done that' experience — I used essentially the technique described in other answers where the non-debug build does not see the printf-like statements for a number of years (more than a decade). But I came across the advice in TPOP (see my previous comment), and then did enable some debugging code after a number of years, and ran into problems of changed context breaking the debugging. Several times, having the printing always validated has saved me from later problems.
I use NDEBUG to control assertions only, and a separate macro (usually DEBUG) to control whether debug tracing is built into the program. Even when the debug tracing is built in, I frequently do not want debug output to appear unconditionally, so I have mechanism to control whether the output appears (debug levels, and instead of calling fprintf() directly, I call a debug print function that only conditionally prints so the same build of the code can print or not print based on program options). I also have a 'multiple-subsystem' version of the code for bigger programs, so that I can have different sections of the program producing different amounts of trace - under runtime control.
I am advocating that for all builds, the compiler should see the diagnostic statements; however, the compiler won't generate any code for the debugging trace statements unless debug is enabled. Basically, it means that all of your code is checked by the compiler every time you compile - whether for release or debugging. This is a good thing!
debug.h - version 1.2 (1990-05-01)
/*
#(#)File: $RCSfile: debug.h,v $
#(#)Version: $Revision: 1.2 $
#(#)Last changed: $Date: 1990/05/01 12:55:39 $
#(#)Purpose: Definitions for the debugging system
#(#)Author: J Leffler
*/
#ifndef DEBUG_H
#define DEBUG_H
/* -- Macro Definitions */
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x)
#endif /* DEBUG */
/* -- Declarations */
#ifdef DEBUG
extern int debug;
#endif
#endif /* DEBUG_H */
debug.h - version 3.6 (2008-02-11)
/*
#(#)File: $RCSfile: debug.h,v $
#(#)Version: $Revision: 3.6 $
#(#)Last changed: $Date: 2008/02/11 06:46:37 $
#(#)Purpose: Definitions for the debugging system
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 1990-93,1997-99,2003,2005,2008
#(#)Product: :PRODUCT:
*/
#ifndef DEBUG_H
#define DEBUG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
/*
** Usage: TRACE((level, fmt, ...))
** "level" is the debugging level which must be operational for the output
** to appear. "fmt" is a printf format string. "..." is whatever extra
** arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike.
*/
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x) do { if (0) db_print x; } while (0)
#endif /* DEBUG */
#ifndef lint
#ifdef DEBUG
/* This string can't be made extern - multiple definition in general */
static const char jlss_id_debug_enabled[] = "#(#)*** DEBUG ***";
#endif /* DEBUG */
#ifdef MAIN_PROGRAM
const char jlss_id_debug_h[] = "#(#)$Id: debug.h,v 3.6 2008/02/11 06:46:37 jleffler Exp $";
#endif /* MAIN_PROGRAM */
#endif /* lint */
#include <stdio.h>
extern int db_getdebug(void);
extern int db_newindent(void);
extern int db_oldindent(void);
extern int db_setdebug(int level);
extern int db_setindent(int i);
extern void db_print(int level, const char *fmt,...);
extern void db_setfilename(const char *fn);
extern void db_setfileptr(FILE *fp);
extern FILE *db_getfileptr(void);
/* Semi-private function */
extern const char *db_indent(void);
/**************************************\
** MULTIPLE DEBUGGING SUBSYSTEMS CODE **
\**************************************/
/*
** Usage: MDTRACE((subsys, level, fmt, ...))
** "subsys" is the debugging system to which this statement belongs.
** The significance of the subsystems is determined by the programmer,
** except that the functions such as db_print refer to subsystem 0.
** "level" is the debugging level which must be operational for the
** output to appear. "fmt" is a printf format string. "..." is
** whatever extra arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
*/
#ifdef DEBUG
#define MDTRACE(x) db_mdprint x
#else
#define MDTRACE(x) do { if (0) db_mdprint x; } while (0)
#endif /* DEBUG */
extern int db_mdgetdebug(int subsys);
extern int db_mdparsearg(char *arg);
extern int db_mdsetdebug(int subsys, int level);
extern void db_mdprint(int subsys, int level, const char *fmt,...);
extern void db_mdsubsysnames(char const * const *names);
#endif /* DEBUG_H */
Single argument variant for C99 or later
Kyle Brandt asked:
Anyway to do this so debug_print still works even if there are no arguments? For example:
debug_print("Foo");
There's one simple, old-fashioned hack:
debug_print("%s\n", "Foo");
The GCC-only solution shown below also provides support for that.
However, you can do it with the straight C99 system by using:
#define debug_print(...) \
do { if (DEBUG) fprintf(stderr, __VA_ARGS__); } while (0)
Compared to the first version, you lose the limited checking that requires the 'fmt' argument, which means that someone could try to call 'debug_print()' with no arguments (but the trailing comma in the argument list to fprintf() would fail to compile). Whether the loss of checking is a problem at all is debatable.
GCC-specific technique for a single argument
Some compilers may offer extensions for other ways of handling variable-length argument lists in macros. Specifically, as first noted in the comments by Hugo Ideler, GCC allows you to omit the comma that would normally appear after the last 'fixed' argument to the macro. It also allows you to use ##__VA_ARGS__ in the macro replacement text, which deletes the comma preceding the notation if, but only if, the previous token is a comma:
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0)
This solution retains the benefit of requiring the format argument while accepting optional arguments after the format.
This technique is also supported by Clang for GCC compatibility.
Why the do-while loop?
What's the purpose of the do while here?
You want to be able to use the macro so it looks like a function call, which means it will be followed by a semi-colon. Therefore, you have to package the macro body to suit. If you use an if statement without the surrounding do { ... } while (0), you will have:
/* BAD - BAD - BAD */
#define debug_print(...) \
if (DEBUG) fprintf(stderr, __VA_ARGS__)
Now, suppose you write:
if (x > y)
debug_print("x (%d) > y (%d)\n", x, y);
else
do_something_useful(x, y);
Unfortunately, that indentation doesn't reflect the actual control of flow, because the preprocessor produces code equivalent to this (indented and braces added to emphasize the actual meaning):
if (x > y)
{
if (DEBUG)
fprintf(stderr, "x (%d) > y (%d)\n", x, y);
else
do_something_useful(x, y);
}
The next attempt at the macro might be:
/* BAD - BAD - BAD */
#define debug_print(...) \
if (DEBUG) { fprintf(stderr, __VA_ARGS__); }
And the same code fragment now produces:
if (x > y)
if (DEBUG)
{
fprintf(stderr, "x (%d) > y (%d)\n", x, y);
}
; // Null statement from semi-colon after macro
else
do_something_useful(x, y);
And the else is now a syntax error. The do { ... } while(0) loop avoids both these problems.
There's one other way of writing the macro which might work:
/* BAD - BAD - BAD */
#define debug_print(...) \
((void)((DEBUG) ? fprintf(stderr, __VA_ARGS__) : 0))
This leaves the program fragment shown as valid. The (void) cast prevents it being used in contexts where a value is required — but it could be used as the left operand of a comma operator where the do { ... } while (0) version cannot. If you think you should be able to embed debug code into such expressions, you might prefer this. If you prefer to require the debug print to act as a full statement, then the do { ... } while (0) version is better. Note that if the body of the macro involved any semi-colons (roughly speaking), then you can only use the do { ... } while(0) notation. It always works; the expression statement mechanism can be more difficult to apply. You might also get warnings from the compiler with the expression form that you'd prefer to avoid; it will depend on the compiler and the flags you use.
TPOP was previously at http://plan9.bell-labs.com/cm/cs/tpop and http://cm.bell-labs.com/cm/cs/tpop but both are now (2015-08-10) broken.
Code in GitHub
If you're curious, you can look at this code in GitHub in my SOQ (Stack
Overflow Questions) repository as files debug.c, debug.h and mddebug.c in the
src/libsoq
sub-directory.
I use something like this:
#ifdef DEBUG
#define D if(1)
#else
#define D if(0)
#endif
Than I just use D as a prefix:
D printf("x=%0.3f\n",x);
Compiler sees the debug code, there is no comma problem and it works everywhere. Also it works when printf is not enough, say when you must dump an array or calculate some diagnosing value that is redundant to the program itself.
EDIT: Ok, it might generate a problem when there is else somewhere near that can be intercepted by this injected if. This is a version that goes over it:
#ifdef DEBUG
#define D
#else
#define D for(;0;)
#endif
For a portable (ISO C90) implementation, you could use double parentheses, like this;
#include <stdio.h>
#include <stdarg.h>
#ifndef NDEBUG
# define debug_print(msg) stderr_printf msg
#else
# define debug_print(msg) (void)0
#endif
void
stderr_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int
main(int argc, char *argv[])
{
debug_print(("argv[0] is %s, argc is %d\n", argv[0], argc));
return 0;
}
or (hackish, wouldn't recommend it)
#include <stdio.h>
#define _ ,
#ifndef NDEBUG
# define debug_print(msg) fprintf(stderr, msg)
#else
# define debug_print(msg) (void)0
#endif
int
main(int argc, char *argv[])
{
debug_print("argv[0] is %s, argc is %d"_ argv[0] _ argc);
return 0;
}
Here's the version I use:
#ifdef NDEBUG
#define Dprintf(FORMAT, ...) ((void)0)
#define Dputs(MSG) ((void)0)
#else
#define Dprintf(FORMAT, ...) \
fprintf(stderr, "%s() in %s, line %i: " FORMAT "\n", \
__func__, __FILE__, __LINE__, __VA_ARGS__)
#define Dputs(MSG) Dprintf("%s", MSG)
#endif
I would do something like
#ifdef DEBUG
#define debug_print(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#else
#define debug_print(fmt, ...) do {} while (0)
#endif
I think this is cleaner.
According to http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html,
there should be a ## before __VA_ARGS__.
Otherwise, a macro #define dbg_print(format, ...) printf(format, __VA_ARGS__) will not compile the following example: dbg_print("hello world");.
#define debug_print(FMT, ARGS...) do { \
if (DEBUG) \
fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
} while (0)
This is what I use:
#if DBG
#include <stdio.h>
#define DBGPRINT printf
#else
#define DBGPRINT(...) /**/
#endif
It has the nice benefit to handle printf properly, even without additional arguments. In case DBG ==0, even the dumbest compiler gets nothing to chew upon, so no code is generated.
So, when using gcc, I like:
#define DBGI(expr) ({int g2rE3=expr; fprintf(stderr, "%s:%d:%s(): ""%s->%i\n", __FILE__, __LINE__, __func__, #expr, g2rE3); g2rE3;})
Because it can be inserted into code.
Suppose you're trying to debug
printf("%i\n", (1*2*3*4*5*6));
720
Then you can change it to:
printf("%i\n", DBGI(1*2*3*4*5*6));
hello.c:86:main(): 1*2*3*4*5*6->720
720
And you can get an analysis of what expression was evaluated to what.
It's protected against the double-evaluation problem, but the absence of gensyms does leave it open to name-collisions.
However it does nest:
DBGI(printf("%i\n", DBGI(1*2*3*4*5*6)));
hello.c:86:main(): 1*2*3*4*5*6->720
720
hello.c:86:main(): printf("%i\n", DBGI(1*2*3*4*5*6))->4
So I think that as long as you avoid using g2rE3 as a variable name, you'll be OK.
Certainly I've found it (and allied versions for strings, and versions for debug levels etc) invaluable.
My favourite of the below is var_dump, which when called as:
var_dump("%d", count);
produces output like:
patch.c:150:main(): count = 0
Credit to #"Jonathan Leffler". All are C89-happy:
Code
#define DEBUG 1
#include <stdarg.h>
#include <stdio.h>
void debug_vprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
/* Call as: (DOUBLE PARENTHESES ARE MANDATORY) */
/* var_debug(("outfd = %d, somefailed = %d\n", outfd, somefailed)); */
#define var_debug(x) do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): ", \
__FILE__, __LINE__, __func__); debug_vprintf x; }} while (0)
/* var_dump("%s" variable_name); */
#define var_dump(fmt, var) do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): ", \
__FILE__, __LINE__, __func__); debug_vprintf ("%s = " fmt, #var, var); }} while (0)
#define DEBUG_HERE do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): HERE\n", \
__FILE__, __LINE__, __func__); }} while (0)
I've been stewing on how to do this for years, and finally come up with a solution. However, I didn't know that there were other solutions here already. First, at difference with Leffler's answer, I don't see his argument that debug prints should always be compiled. I'd rather not have tons of unneeded code executing in my project, when not needed, in cases where I need to test and they might not be getting optimized out.
Not compiling every time might sound worse than it is in actual practice. You do wind up with debug prints that don't compile sometimes, but it's not so hard to compile and test them before finalizing a project. With this system, if you are using three levels of debugs, just put it on debug message level three, fix your compile errors and check for any others before you finalize yer code. (Since of course, debug statements compiling are no guarantee that they are still working as intended.)
My solution provides for levels of debug detail also; and if you set it to the highest level, they all compile. If you've been using a high debug detail level recently, they all were able to compile at that time. Final updates should be pretty easy. I've never needed more than three levels, but Jonathan says he's used nine. This method (like Leffler's) can be extended to any number of levels. The usage of my method may be simpler; requiring just two statements when used in your code. I am, however, coding the CLOSE macro too - although it doesn't do anything. It might if I were sending to a file.
Against the cost the extra step of testing them to see that they will compile before delivery, is that
You must trust them to get optimized out, which admittedly SHOULD happen if you have a sufficient optimization level.
Furthermore, they probably won't if you make a release compile with optimization turned off for testing purposes (which is admittedly rare); and they almost certainly won't at all during debug - thereby executing dozens or hundreds of "if (DEBUG)" statements at runtime; thus slowing execution (which is my principle objection) and less importantly, increasing your executable or dll size; and hence execution and compile times. Jonathan, however, informs me his method can be made to also not compile statements at all.
Branches are actually relatively pretty costly in modern pre-fetching processors. Maybe not a big deal if your app is not a time-critical one; but if performance is an issue, then, yes, a big enough deal that I'd prefer to opt for somewhat faster-executing debug code (and possibly faster release, in rare cases, as noted).
So, what I wanted is a debug print macro that does not compile if it is not to be printed, but does if it is. I also wanted levels of debugging, so that, e.g. if I wanted performance-crucial parts of the code not to print at some times, but to print at others, I could set a debug level, and have extra debug prints kick in. I came across a way to implement debug levels that determined if the print was even compiled or not. I achieved it this way:
DebugLog.h:
// FILE: DebugLog.h
// REMARKS: This is a generic pair of files useful for debugging. It provides three levels of
// debug logging, currently; in addition to disabling it. Level 3 is the most information.
// Levels 2 and 1 have progressively more. Thus, you can write:
// DEBUGLOG_LOG(1, "a number=%d", 7);
// and it will be seen if DEBUG is anything other than undefined or zero. If you write
// DEBUGLOG_LOG(3, "another number=%d", 15);
// it will only be seen if DEBUG is 3. When not being displayed, these routines compile
// to NOTHING. I reject the argument that debug code needs to always be compiled so as to
// keep it current. I would rather have a leaner and faster app, and just not be lazy, and
// maintain debugs as needed. I don't know if this works with the C preprocessor or not,
// but the rest of the code is fully C compliant also if it is.
#define DEBUG 1
#ifdef DEBUG
#define DEBUGLOG_INIT(filename) debuglog_init(filename)
#else
#define debuglog_init(...)
#endif
#ifdef DEBUG
#define DEBUGLOG_CLOSE debuglog_close
#else
#define debuglog_close(...)
#endif
#define DEBUGLOG_LOG(level, fmt, ...) DEBUGLOG_LOG ## level (fmt, ##__VA_ARGS__)
#if DEBUG == 0
#define DEBUGLOG_LOG0(...)
#endif
#if DEBUG >= 1
#define DEBUGLOG_LOG1(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG1(...)
#endif
#if DEBUG >= 2
#define DEBUGLOG_LOG2(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG2(...)
#endif
#if DEBUG == 3
#define DEBUGLOG_LOG3(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG3(...)
#endif
void debuglog_init(char *filename);
void debuglog_close(void);
void debuglog_log(char* format, ...);
DebugLog.cpp:
// FILE: DebugLog.h
// REMARKS: This is a generic pair of files useful for debugging. It provides three levels of
// debug logging, currently; in addition to disabling it. See DebugLog.h's remarks for more
// info.
#include <stdio.h>
#include <stdarg.h>
#include "DebugLog.h"
FILE *hndl;
char *savedFilename;
void debuglog_init(char *filename)
{
savedFilename = filename;
hndl = fopen(savedFilename, "wt");
fclose(hndl);
}
void debuglog_close(void)
{
//fclose(hndl);
}
void debuglog_log(char* format, ...)
{
hndl = fopen(savedFilename,"at");
va_list argptr;
va_start(argptr, format);
vfprintf(hndl, format, argptr);
va_end(argptr);
fputc('\n',hndl);
fclose(hndl);
}
Using the macros
To use it, just do:
DEBUGLOG_INIT("afile.log");
To write to the log file, just do:
DEBUGLOG_LOG(1, "the value is: %d", anint);
To close it, you do:
DEBUGLOG_CLOSE();
although currently this isn't even necessary, technically speaking, as it does nothing. I'm still using the CLOSE right now, however, in case I change my mind about how it works, and want to leave the file open between logging statements.
Then, when you want to turn on debug printing, just edit the first #define in the header file to say, e.g.
#define DEBUG 1
To have logging statements compile to nothing, do
#define DEBUG 0
If you need info from a frequently executed piece of code (i.e. a high level of detail), you may want to write:
DEBUGLOG_LOG(3, "the value is: %d", anint);
If you define DEBUG to be 3, logging levels 1, 2 & 3 compile. If you set it to 2, you get logging levels 1 & 2. If you set it to 1, you only get logging level 1 statements.
As to the do-while loop, since this evaluates to either a single function or nothing, instead of an if statement, the loop is not needed. OK, castigate me for using C instead of C++ IO (and Qt's QString::arg() is a safer way of formatting variables when in Qt, too — it's pretty slick, but takes more code and the formatting documentation isn't as organized as it might be - but still I've found cases where its preferable), but you can put whatever code in the .cpp file you want. It also might be a class, but then you would need to instantiate it and keep up with it, or do a new() and store it. This way, you just drop the #include, init and optionally close statements into your source, and you are ready to begin using it. It would make a fine class, however, if you are so inclined.
I'd previously seen a lot of solutions, but none suited my criteria as well as this one.
It can be extended to do as many levels as you like.
It compiles to nothing if not printing.
It centralizes IO in one easy-to-edit place.
It's flexible, using printf formatting.
Again, it does not slow down debug runs, whereas always-compiling debug prints are always executed in debug mode. If you are doing computer science, and not easier to write information processing, you may find yourself running a CPU-consuming simulator, to see e.g. where the debugger stops it with an index out of range for a vector. These run extra-slowly in debug mode already. The mandatory execution of hundreds of debug prints will necessarily slow such runs down even further. For me, such runs are not uncommon.
Not terribly significant, but in addition:
It requires no hack to print without arguments (e.g. DEBUGLOG_LOG(3, "got here!");); thus allowing you to use, e.g. Qt's safer .arg() formatting. It works on MSVC, and thus, probably gcc. It uses ## in the #defines, which is non-standard, as Leffler points out, but is widely supported. (You can recode it not to use ## if necessary, but you will have to use a hack such as he provides.)
Warning: If you forget to provide the logging level argument, MSVC unhelpfully claims the identifier is not defined.
You might want to use a preprocessor symbol name other than DEBUG, as some source also defines that symbol (eg. progs using ./configure commands to prepare for building). It seemed natural to me when I developed it. I developed it in an application where the DLL is being used by something else, and it's more convent to send log prints to a file; but changing it to vprintf() would work fine, too.
I hope this saves many of you grief about figuring out the best way to do debug logging; or shows you one you might prefer. I've half-heartedly been trying to figure this one out for decades. Works in MSVC 2012 & 2015, and thus probably on gcc; as well as probably working on many others, but I haven't tested it on them.
I mean to make a streaming version of this one day, too.
Note: Thanks go to Leffler, who has cordially helped me format my message better for StackOverflow.
#define PRINT_LOG(str_format, ...) { \
time_t curtime=time (NULL); \
struct tm *ltm = localtime (&curtime); \
printf("[%d-%02d-%02d %02d:%02d:%02d] " str_format, \
ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, \
ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ##__VA_ARGS__); \
}
PRINT_LOG("[%d] Serving client, str=%s, number=%d\n", getpid(), "my str", 10);
I believe this variation of the theme gives debug categories without the need to have a separate macro name per category.
I used this variation in an Arduino project where program space is limited to 32K and dynamic memory is limited to 2K. The addition of debug statements and trace debug strings quickly uses up space. So it is essential to be able to limit the debug trace that is included at compile time to the minimum necessary each time the code is built.
debug.h
#ifndef DEBUG_H
#define DEBUG_H
#define PRINT(DEBUG_CATEGORY, VALUE) do { if (DEBUG_CATEGORY & DEBUG_MASK) Serial.print(VALUE);} while (0);
#endif
calling .cpp file
#define DEBUG_MASK 0x06
#include "Debug.h"
...
PRINT(4, "Time out error,\t");
...
If you don't care that the output goes to stdout, you can use this:
int doDebug = DEBUG; // Where DEBUG may be supplied in compiler command
#define trace if (doDebug) printf
trace("whatever %d, %i\n", arg1, arg2);

Multiline macro in c (#if-#endif)

my code:
#define DEBUG 3
#define TEST(...)
#if (DEBUG == 3) \
printf("%s: %s\n", __FILE__, __VA_ARGS__);
#endif
int main(void) {
TEST("TEST")
return 0;
}
Error: missing the binary operator before token 'printf'.
I don't understand what's the problem
You're trying to put the #if inside the macro, but C doesn't permit that kind of thing. The reason it's failing is the printf inside the #if is unexpected. This is a common request, but it's just not allowed.
However, you can accomplish the same thing by changing the way you do the test:
#include <stdio.h>
#define DEBUG 3
#if (DEBUG == 3)
# define TEST(...) printf("%s: %s\n", __FILE__, __VA_ARGS__);
#else
# define TEST(...)
#endif
int main(void) {
TEST("TEST")
return 0;
}
EDIT: Though test-type macros like this are common, this is not a great way to do it because it can lead to unhappy surprises in debug/nondebug situations.
What happens in this case?
if (something)
TEST("blah")
else
TEST("no")
This works as you expect in debug mode, but won't even compile in production because it devolves to if (something) else - it doesn't even have a closing semicolon. It's easy to find other examples that are much more devious.
Hiding a semicolon inside a macro like this is usually asking for trouble, so the better approach is to make them function-like where you have to provide the semicolon yourself, and the most obvious way to do it is:
# #define TEST(...) printf("%s: %s\n", __FILE__, __VA_ARGS__) // no semicolon
...
if (something)
TEST("blah");
else
TEST("no");
This is better and leads to less surprises, but it's still a little troublesome in that it can leave a dangling semicolon lying around, which some compilers object to.
A fix for this can be:
#if (DEBUG == 3)
# define TEST(...) printf("%s: %s\n", __FILE__, __VA_ARGS__)
#else
# define TEST(...) ((void)0) // dummy statement
#endif
which at least quiets the compiler. There are other approaches here too.
In C #define cannot "contain" #ifs

Macro to turn off printf statements

What MACRO can be used to switch off printf statements, rather than removing them all for deployment builds, I just want to switch them off, skip them, ignore them.
EDIT: I personally use gcc, but code is part of a larger project which will be compiled on a Panda board running Ubuntu.
Not exactly what you ask for, but I use this construct in my code for debug output when I do not have a proper logging system handy:
#if 1
#define SPAM(a) printf a
#else
#define SPAM(a) (void)0
#endif
So I can do this all over my code
SPAM(("foo: %d\n", 42));
and then disable all of them by changing 1 to 0 in #if above.
But if you have variadic macro support in all compilers that you write code for, then you may go for other answers and just redefine printf. (That being said, I find it useful to distinct debugging prints from regular ones in code — using a different function name helps readability.)
Note that you also can redirect stdout to the /dev/null, but I assume that you want to get rid from runtime overhead as well.
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
See also C #define macro for debug printing which discusses some important issues closely related to this.
Two options, either:
#define printf(...)
(requires C99 variadic macro parameters), you need to put it in some common header file which is never included before stdio.h, if there is one..
Or you can tell the linker to link it to something else, in GCC you would define
int wrap_printf(void) {return 0;}
and link using
--wrap printf
All that said, you should probably not be using printf for printing debug output, but rather a macro or utility function (which in turn can use printf if you'd like) which you have better control over.
Hope that helps.
If you want to avoid the potential warning that Jonathan's answer may give you and if you don't mind an empty call to printf you could also do something like
#define printf(...) printf("")
This works because C macros are not recursive. The expanded printf("") will just be left as such.
Another variant (since you are using gcc) would be something like
inline int ignore_printf(char const*, ...)
__attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }
#define printf ignore_printf
and in one compilation unit
int ignore_printf(char const*, ...)
I use to prefix the debug printf()s (not all of them) with PDEB.
For the debug builds, I compile with -DPDEB= (nothing)
For the release builds, I compile with -DPDEB="0&&" or -DPDEB="0 && "
That way, the following code (test.c):
#include <stdio.h>
void main(void) {
printf("normal print\n");
PDEB printf("debug print\n");
}
outputs:
either (in release mode):
normal print
either (in debug mode):
normal print
debug print
Ideally, one could aim for turning the PDEB into the "//" (comments mark), except that this is not possible under the standard pre-/processing chain.
Another possibility would be something like freopen("/dev/null", "w", stdout);
This doesn't exactly disable printf though -- it's roughly equivalent to running your program with stdout redirected to /dev/null, like: ./myprog > /dev/null at the shell prompt.
I included #define printf // in common header file. It will suppress all the printf.
Below simple function serves the purpose, I use the same.
int printf(const char *fmt, ...)
{
return (0)
}
Use this macro to enable or disable the printf.
//Uncomment the following line to enable the printf function.
//#define ENABLE_PRINTF
#ifdef ENABLE_PRINTF
#define DEBUG_PRINTF(f,...) printf(f,##__VA_ARGS__)
#else
#define DEBUG_PRINTF(f,...)
#endif
Then call "DEBUG_PRINTF" instead of "printf".
For example:
DEBUG_PRINTF("Hello world: %d", whateverCount);
I have used two macros for this. The first one defines the condition to print. In this simple example we print any time the parameter is not zero. More complex expressions can be used.
The second one determines, based on the first macro, to call or not printf.
If the condition can be determined by the compiler (with the right optimization settings) no code is generated.
If the condition cannot be determined at compile time then will be at run time. One of the advantages of this method is that if printf is not going to happen then the whole printf is not evaluated avoiding many conversions to string that can happen in a complex printf statement.
#define need_to_print(flag) ((flag) != 0))
#define my_printf(debug_level, ...) \
({ \
if(need_to_print(debug_level)) \
printf(__VA_ARGS__); \
})
to use it call my_printf instead of printf and add a parameter at the beginning for the print condition.
my_printf(0, "value = %d\n", vv); //this will not print
my_printf(1, "value = %d\n", vv); //this will print
my_printf(print_debug, "value = %d\n", vv); //this will print if print_debug != 0
the ( ... ) parenthesis surrounding the macro make it a single statement.

Can you #define a comment in C?

I'm trying to do a debug system but it seems not to work.
What I wanted to accomplish is something like this:
#ifndef DEBUG
#define printd //
#else
#define printd printf
#endif
Is there a way to do that? I have lots of debug messages and I won't like to do:
if (DEBUG)
printf(...)
code
if (DEBUG)
printf(...)
...
No, you can't. Comments are removed from the code before any processing of preprocessing directives begin. For this reason you can't include comment into a macro.
Also, any attempts to "form" a comment later by using any macro trickery are not guaranteed to work. The compiler is not required to recognize "late" comments as comments.
The best way to implement what you want is to use macros with variable arguments in C99 (or, maybe, using the compiler extensions).
A common trick is to do this:
#ifdef DEBUG
#define OUTPUT(x) printf x
#else
#define OUTPUT(x)
#endif
#include <stdio.h>
int main(void)
{
OUTPUT(("%s line %i\n", __FILE__, __LINE__));
return 0;
}
This way you have the whole power of printf() available to you, but you have to put up with the double brackets to make the macro work.
The point of the double brackets is this: you need one set to indicate that it's a macro call, but you can't have an indeterminate number of arguments in a macro in C89. However, by putting the arguments in their own set of brackets they get interpreted as a single argument. When the macro is expanded when DEBUG is defined, the replacement text is the word printf followed by the singl argument, which is actually several items in brackets. The brackets then get interpreted as the brackets needed in the printf function call, so it all works out.
С99 way:
#ifdef DEBUG
#define printd(...) printf(__VA_ARGS__)
#else
#define printd(...)
#endif
Well, this one doesn't require C99 but assumes compiler has optimization turned on for release version:
#ifdef DEBUG
#define printd printf
#else
#define printd if (1) {} else printf
#endif
On some compilers (including MS VS2010) this will work,
#define CMT / ## /
but no grantees for all compilers.
You can put all your debug call in a function, let call it printf_debug and put the DEBUG inside this function.
The compiler will optimize the empty function.
The standard way is to use
#ifndef DEBUG
#define printd(fmt, ...) do { } while(0)
#else
#define printd(fmt, ...) printf(fmt, __VA_ARGS__)
#endif
That way, when you add a semi-colon on the end, it does what you want.
As there is no operation the compiler will compile out the "do...while"
Untested:
Edit: Tested, using it by myself by now :)
#define DEBUG 1
#define printd(fmt,...) if(DEBUG)printf(fmt, __VA_ARGS__)
requires you to not only define DEBUG but also give it a non-zer0 value.
Appendix:
Also works well with std::cout
In C++17 I like to use constexpr for something like this
#ifndef NDEBUG
constexpr bool DEBUG = true;
#else
constexpr bool DEBUG = false;
#endif
Then you can do
if constexpr (DEBUG) /* debug code */
The caveats are that, unlike a preprocessor macro, you are limited in scope. You can neither declare variables in one debug conditional that are accessible from another, nor can they be used at outside function scopes.
You can take advantage of if. For example,
#ifdef debug
#define printd printf
#else
#define printd if (false) printf
#endif
Compiler will remove these unreachable code if you set a optimization flag like -O2. This method also useful for std::cout.
As noted by McKay, you will run into problems if you simply try to replace printd with //. Instead, you could use variadric macros to replace printd with a function that does nothing as in the following.
#ifndef DEBUG
#define printd(...) do_nothing()
#else
#define printd(...) printf(__VA_ARGS__)
#endif
void do_nothing() { ; }
Using a debugger like GDB might help too, but sometimes a quick printf is enough.
I use this construct a lot:
#define DEBUG 1
#if DEBUG
#if PROG1
#define DEBUGSTR(msg...) { printf("P1: "); printf( msg); }
#else
#define DEBUGSTR(msg...) { printf("P2: "); printf( msg); }
#endif
#else
#define DEBUGSTR(msg...) ((void) 0)
#endif
This way I can tell in my console which program is giving which error message... also, I can search easily for my error messages...
Personally, I don't like #defining just part of an expression...
It's been done. I don't recommend it. No time to test but the mechanism is kind of like this:
#define printd_CAT(x) x ## x
#ifndef DEBUG
#define printd printd_CAT(/)
#else
#define printd printf
#endif
This works if your compiler processes // comments in the compiler itself (there's no guarantee like the ANSI guarantee that there are two passes for /* comments).

#define macro for debug printing in C?

Trying to create a macro which can be used for print debug messages when DEBUG is defined, like the following pseudo code:
#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)
How is this accomplished with a macro?
If you use a C99 or later compiler
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
It assumes you are using C99 (the variable argument list notation is not supported in earlier versions). The do { ... } while (0) idiom ensures that the code acts like a statement (function call). The unconditional use of the code ensures that the compiler always checks that your debug code is valid — but the optimizer will remove the code when DEBUG is 0.
If you want to work with #ifdef DEBUG, then change the test condition:
#ifdef DEBUG
#define DEBUG_TEST 1
#else
#define DEBUG_TEST 0
#endif
And then use DEBUG_TEST where I used DEBUG.
If you insist on a string literal for the format string (probably a good idea anyway), you can also introduce things like __FILE__, __LINE__ and __func__ into the output, which can improve the diagnostics:
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
__LINE__, __func__, __VA_ARGS__); } while (0)
This relies on string concatenation to create a bigger format string than the programmer writes.
If you use a C89 compiler
If you are stuck with C89 and no useful compiler extension, then there isn't a particularly clean way to handle it. The technique I used to use was:
#define TRACE(x) do { if (DEBUG) dbg_printf x; } while (0)
And then, in the code, write:
TRACE(("message %d\n", var));
The double-parentheses are crucial — and are why you have the funny notation in the macro expansion. As before, the compiler always checks the code for syntactic validity (which is good) but the optimizer only invokes the printing function if the DEBUG macro evaluates to non-zero.
This does require a support function — dbg_printf() in the example — to handle things like 'stderr'. It requires you to know how to write varargs functions, but that isn't hard:
#include <stdarg.h>
#include <stdio.h>
void dbg_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
You can also use this technique in C99, of course, but the __VA_ARGS__ technique is neater because it uses regular function notation, not the double-parentheses hack.
Why is it crucial that the compiler always see the debug code?
[Rehashing comments made to another answer.]
One central idea behind both the C99 and C89 implementations above is that the compiler proper always sees the debugging printf-like statements. This is important for long-term code — code that will last a decade or two.
Suppose a piece of code has been mostly dormant (stable) for a number of years, but now needs to be changed. You re-enable debugging trace - but it is frustrating to have to debug the debugging (tracing) code because it refers to variables that have been renamed or retyped, during the years of stable maintenance. If the compiler (post pre-processor) always sees the print statement, it ensures that any surrounding changes have not invalidated the diagnostics. If the compiler does not see the print statement, it cannot protect you against your own carelessness (or the carelessness of your colleagues or collaborators). See 'The Practice of Programming' by Kernighan and Pike, especially Chapter 8 (see also Wikipedia on TPOP).
This is 'been there, done that' experience — I used essentially the technique described in other answers where the non-debug build does not see the printf-like statements for a number of years (more than a decade). But I came across the advice in TPOP (see my previous comment), and then did enable some debugging code after a number of years, and ran into problems of changed context breaking the debugging. Several times, having the printing always validated has saved me from later problems.
I use NDEBUG to control assertions only, and a separate macro (usually DEBUG) to control whether debug tracing is built into the program. Even when the debug tracing is built in, I frequently do not want debug output to appear unconditionally, so I have mechanism to control whether the output appears (debug levels, and instead of calling fprintf() directly, I call a debug print function that only conditionally prints so the same build of the code can print or not print based on program options). I also have a 'multiple-subsystem' version of the code for bigger programs, so that I can have different sections of the program producing different amounts of trace - under runtime control.
I am advocating that for all builds, the compiler should see the diagnostic statements; however, the compiler won't generate any code for the debugging trace statements unless debug is enabled. Basically, it means that all of your code is checked by the compiler every time you compile - whether for release or debugging. This is a good thing!
debug.h - version 1.2 (1990-05-01)
/*
#(#)File: $RCSfile: debug.h,v $
#(#)Version: $Revision: 1.2 $
#(#)Last changed: $Date: 1990/05/01 12:55:39 $
#(#)Purpose: Definitions for the debugging system
#(#)Author: J Leffler
*/
#ifndef DEBUG_H
#define DEBUG_H
/* -- Macro Definitions */
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x)
#endif /* DEBUG */
/* -- Declarations */
#ifdef DEBUG
extern int debug;
#endif
#endif /* DEBUG_H */
debug.h - version 3.6 (2008-02-11)
/*
#(#)File: $RCSfile: debug.h,v $
#(#)Version: $Revision: 3.6 $
#(#)Last changed: $Date: 2008/02/11 06:46:37 $
#(#)Purpose: Definitions for the debugging system
#(#)Author: J Leffler
#(#)Copyright: (C) JLSS 1990-93,1997-99,2003,2005,2008
#(#)Product: :PRODUCT:
*/
#ifndef DEBUG_H
#define DEBUG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
/*
** Usage: TRACE((level, fmt, ...))
** "level" is the debugging level which must be operational for the output
** to appear. "fmt" is a printf format string. "..." is whatever extra
** arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
** -- See chapter 8 of 'The Practice of Programming', by Kernighan and Pike.
*/
#ifdef DEBUG
#define TRACE(x) db_print x
#else
#define TRACE(x) do { if (0) db_print x; } while (0)
#endif /* DEBUG */
#ifndef lint
#ifdef DEBUG
/* This string can't be made extern - multiple definition in general */
static const char jlss_id_debug_enabled[] = "#(#)*** DEBUG ***";
#endif /* DEBUG */
#ifdef MAIN_PROGRAM
const char jlss_id_debug_h[] = "#(#)$Id: debug.h,v 3.6 2008/02/11 06:46:37 jleffler Exp $";
#endif /* MAIN_PROGRAM */
#endif /* lint */
#include <stdio.h>
extern int db_getdebug(void);
extern int db_newindent(void);
extern int db_oldindent(void);
extern int db_setdebug(int level);
extern int db_setindent(int i);
extern void db_print(int level, const char *fmt,...);
extern void db_setfilename(const char *fn);
extern void db_setfileptr(FILE *fp);
extern FILE *db_getfileptr(void);
/* Semi-private function */
extern const char *db_indent(void);
/**************************************\
** MULTIPLE DEBUGGING SUBSYSTEMS CODE **
\**************************************/
/*
** Usage: MDTRACE((subsys, level, fmt, ...))
** "subsys" is the debugging system to which this statement belongs.
** The significance of the subsystems is determined by the programmer,
** except that the functions such as db_print refer to subsystem 0.
** "level" is the debugging level which must be operational for the
** output to appear. "fmt" is a printf format string. "..." is
** whatever extra arguments fmt requires (possibly nothing).
** The non-debug macro means that the code is validated but never called.
*/
#ifdef DEBUG
#define MDTRACE(x) db_mdprint x
#else
#define MDTRACE(x) do { if (0) db_mdprint x; } while (0)
#endif /* DEBUG */
extern int db_mdgetdebug(int subsys);
extern int db_mdparsearg(char *arg);
extern int db_mdsetdebug(int subsys, int level);
extern void db_mdprint(int subsys, int level, const char *fmt,...);
extern void db_mdsubsysnames(char const * const *names);
#endif /* DEBUG_H */
Single argument variant for C99 or later
Kyle Brandt asked:
Anyway to do this so debug_print still works even if there are no arguments? For example:
debug_print("Foo");
There's one simple, old-fashioned hack:
debug_print("%s\n", "Foo");
The GCC-only solution shown below also provides support for that.
However, you can do it with the straight C99 system by using:
#define debug_print(...) \
do { if (DEBUG) fprintf(stderr, __VA_ARGS__); } while (0)
Compared to the first version, you lose the limited checking that requires the 'fmt' argument, which means that someone could try to call 'debug_print()' with no arguments (but the trailing comma in the argument list to fprintf() would fail to compile). Whether the loss of checking is a problem at all is debatable.
GCC-specific technique for a single argument
Some compilers may offer extensions for other ways of handling variable-length argument lists in macros. Specifically, as first noted in the comments by Hugo Ideler, GCC allows you to omit the comma that would normally appear after the last 'fixed' argument to the macro. It also allows you to use ##__VA_ARGS__ in the macro replacement text, which deletes the comma preceding the notation if, but only if, the previous token is a comma:
#define debug_print(fmt, ...) \
do { if (DEBUG) fprintf(stderr, fmt, ##__VA_ARGS__); } while (0)
This solution retains the benefit of requiring the format argument while accepting optional arguments after the format.
This technique is also supported by Clang for GCC compatibility.
Why the do-while loop?
What's the purpose of the do while here?
You want to be able to use the macro so it looks like a function call, which means it will be followed by a semi-colon. Therefore, you have to package the macro body to suit. If you use an if statement without the surrounding do { ... } while (0), you will have:
/* BAD - BAD - BAD */
#define debug_print(...) \
if (DEBUG) fprintf(stderr, __VA_ARGS__)
Now, suppose you write:
if (x > y)
debug_print("x (%d) > y (%d)\n", x, y);
else
do_something_useful(x, y);
Unfortunately, that indentation doesn't reflect the actual control of flow, because the preprocessor produces code equivalent to this (indented and braces added to emphasize the actual meaning):
if (x > y)
{
if (DEBUG)
fprintf(stderr, "x (%d) > y (%d)\n", x, y);
else
do_something_useful(x, y);
}
The next attempt at the macro might be:
/* BAD - BAD - BAD */
#define debug_print(...) \
if (DEBUG) { fprintf(stderr, __VA_ARGS__); }
And the same code fragment now produces:
if (x > y)
if (DEBUG)
{
fprintf(stderr, "x (%d) > y (%d)\n", x, y);
}
; // Null statement from semi-colon after macro
else
do_something_useful(x, y);
And the else is now a syntax error. The do { ... } while(0) loop avoids both these problems.
There's one other way of writing the macro which might work:
/* BAD - BAD - BAD */
#define debug_print(...) \
((void)((DEBUG) ? fprintf(stderr, __VA_ARGS__) : 0))
This leaves the program fragment shown as valid. The (void) cast prevents it being used in contexts where a value is required — but it could be used as the left operand of a comma operator where the do { ... } while (0) version cannot. If you think you should be able to embed debug code into such expressions, you might prefer this. If you prefer to require the debug print to act as a full statement, then the do { ... } while (0) version is better. Note that if the body of the macro involved any semi-colons (roughly speaking), then you can only use the do { ... } while(0) notation. It always works; the expression statement mechanism can be more difficult to apply. You might also get warnings from the compiler with the expression form that you'd prefer to avoid; it will depend on the compiler and the flags you use.
TPOP was previously at http://plan9.bell-labs.com/cm/cs/tpop and http://cm.bell-labs.com/cm/cs/tpop but both are now (2015-08-10) broken.
Code in GitHub
If you're curious, you can look at this code in GitHub in my SOQ (Stack
Overflow Questions) repository as files debug.c, debug.h and mddebug.c in the
src/libsoq
sub-directory.
I use something like this:
#ifdef DEBUG
#define D if(1)
#else
#define D if(0)
#endif
Than I just use D as a prefix:
D printf("x=%0.3f\n",x);
Compiler sees the debug code, there is no comma problem and it works everywhere. Also it works when printf is not enough, say when you must dump an array or calculate some diagnosing value that is redundant to the program itself.
EDIT: Ok, it might generate a problem when there is else somewhere near that can be intercepted by this injected if. This is a version that goes over it:
#ifdef DEBUG
#define D
#else
#define D for(;0;)
#endif
For a portable (ISO C90) implementation, you could use double parentheses, like this;
#include <stdio.h>
#include <stdarg.h>
#ifndef NDEBUG
# define debug_print(msg) stderr_printf msg
#else
# define debug_print(msg) (void)0
#endif
void
stderr_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int
main(int argc, char *argv[])
{
debug_print(("argv[0] is %s, argc is %d\n", argv[0], argc));
return 0;
}
or (hackish, wouldn't recommend it)
#include <stdio.h>
#define _ ,
#ifndef NDEBUG
# define debug_print(msg) fprintf(stderr, msg)
#else
# define debug_print(msg) (void)0
#endif
int
main(int argc, char *argv[])
{
debug_print("argv[0] is %s, argc is %d"_ argv[0] _ argc);
return 0;
}
Here's the version I use:
#ifdef NDEBUG
#define Dprintf(FORMAT, ...) ((void)0)
#define Dputs(MSG) ((void)0)
#else
#define Dprintf(FORMAT, ...) \
fprintf(stderr, "%s() in %s, line %i: " FORMAT "\n", \
__func__, __FILE__, __LINE__, __VA_ARGS__)
#define Dputs(MSG) Dprintf("%s", MSG)
#endif
I would do something like
#ifdef DEBUG
#define debug_print(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
#else
#define debug_print(fmt, ...) do {} while (0)
#endif
I think this is cleaner.
According to http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html,
there should be a ## before __VA_ARGS__.
Otherwise, a macro #define dbg_print(format, ...) printf(format, __VA_ARGS__) will not compile the following example: dbg_print("hello world");.
#define debug_print(FMT, ARGS...) do { \
if (DEBUG) \
fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
} while (0)
This is what I use:
#if DBG
#include <stdio.h>
#define DBGPRINT printf
#else
#define DBGPRINT(...) /**/
#endif
It has the nice benefit to handle printf properly, even without additional arguments. In case DBG ==0, even the dumbest compiler gets nothing to chew upon, so no code is generated.
So, when using gcc, I like:
#define DBGI(expr) ({int g2rE3=expr; fprintf(stderr, "%s:%d:%s(): ""%s->%i\n", __FILE__, __LINE__, __func__, #expr, g2rE3); g2rE3;})
Because it can be inserted into code.
Suppose you're trying to debug
printf("%i\n", (1*2*3*4*5*6));
720
Then you can change it to:
printf("%i\n", DBGI(1*2*3*4*5*6));
hello.c:86:main(): 1*2*3*4*5*6->720
720
And you can get an analysis of what expression was evaluated to what.
It's protected against the double-evaluation problem, but the absence of gensyms does leave it open to name-collisions.
However it does nest:
DBGI(printf("%i\n", DBGI(1*2*3*4*5*6)));
hello.c:86:main(): 1*2*3*4*5*6->720
720
hello.c:86:main(): printf("%i\n", DBGI(1*2*3*4*5*6))->4
So I think that as long as you avoid using g2rE3 as a variable name, you'll be OK.
Certainly I've found it (and allied versions for strings, and versions for debug levels etc) invaluable.
My favourite of the below is var_dump, which when called as:
var_dump("%d", count);
produces output like:
patch.c:150:main(): count = 0
Credit to #"Jonathan Leffler". All are C89-happy:
Code
#define DEBUG 1
#include <stdarg.h>
#include <stdio.h>
void debug_vprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
/* Call as: (DOUBLE PARENTHESES ARE MANDATORY) */
/* var_debug(("outfd = %d, somefailed = %d\n", outfd, somefailed)); */
#define var_debug(x) do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): ", \
__FILE__, __LINE__, __func__); debug_vprintf x; }} while (0)
/* var_dump("%s" variable_name); */
#define var_dump(fmt, var) do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): ", \
__FILE__, __LINE__, __func__); debug_vprintf ("%s = " fmt, #var, var); }} while (0)
#define DEBUG_HERE do { if (DEBUG) { debug_vprintf ("%s:%d:%s(): HERE\n", \
__FILE__, __LINE__, __func__); }} while (0)
I've been stewing on how to do this for years, and finally come up with a solution. However, I didn't know that there were other solutions here already. First, at difference with Leffler's answer, I don't see his argument that debug prints should always be compiled. I'd rather not have tons of unneeded code executing in my project, when not needed, in cases where I need to test and they might not be getting optimized out.
Not compiling every time might sound worse than it is in actual practice. You do wind up with debug prints that don't compile sometimes, but it's not so hard to compile and test them before finalizing a project. With this system, if you are using three levels of debugs, just put it on debug message level three, fix your compile errors and check for any others before you finalize yer code. (Since of course, debug statements compiling are no guarantee that they are still working as intended.)
My solution provides for levels of debug detail also; and if you set it to the highest level, they all compile. If you've been using a high debug detail level recently, they all were able to compile at that time. Final updates should be pretty easy. I've never needed more than three levels, but Jonathan says he's used nine. This method (like Leffler's) can be extended to any number of levels. The usage of my method may be simpler; requiring just two statements when used in your code. I am, however, coding the CLOSE macro too - although it doesn't do anything. It might if I were sending to a file.
Against the cost the extra step of testing them to see that they will compile before delivery, is that
You must trust them to get optimized out, which admittedly SHOULD happen if you have a sufficient optimization level.
Furthermore, they probably won't if you make a release compile with optimization turned off for testing purposes (which is admittedly rare); and they almost certainly won't at all during debug - thereby executing dozens or hundreds of "if (DEBUG)" statements at runtime; thus slowing execution (which is my principle objection) and less importantly, increasing your executable or dll size; and hence execution and compile times. Jonathan, however, informs me his method can be made to also not compile statements at all.
Branches are actually relatively pretty costly in modern pre-fetching processors. Maybe not a big deal if your app is not a time-critical one; but if performance is an issue, then, yes, a big enough deal that I'd prefer to opt for somewhat faster-executing debug code (and possibly faster release, in rare cases, as noted).
So, what I wanted is a debug print macro that does not compile if it is not to be printed, but does if it is. I also wanted levels of debugging, so that, e.g. if I wanted performance-crucial parts of the code not to print at some times, but to print at others, I could set a debug level, and have extra debug prints kick in. I came across a way to implement debug levels that determined if the print was even compiled or not. I achieved it this way:
DebugLog.h:
// FILE: DebugLog.h
// REMARKS: This is a generic pair of files useful for debugging. It provides three levels of
// debug logging, currently; in addition to disabling it. Level 3 is the most information.
// Levels 2 and 1 have progressively more. Thus, you can write:
// DEBUGLOG_LOG(1, "a number=%d", 7);
// and it will be seen if DEBUG is anything other than undefined or zero. If you write
// DEBUGLOG_LOG(3, "another number=%d", 15);
// it will only be seen if DEBUG is 3. When not being displayed, these routines compile
// to NOTHING. I reject the argument that debug code needs to always be compiled so as to
// keep it current. I would rather have a leaner and faster app, and just not be lazy, and
// maintain debugs as needed. I don't know if this works with the C preprocessor or not,
// but the rest of the code is fully C compliant also if it is.
#define DEBUG 1
#ifdef DEBUG
#define DEBUGLOG_INIT(filename) debuglog_init(filename)
#else
#define debuglog_init(...)
#endif
#ifdef DEBUG
#define DEBUGLOG_CLOSE debuglog_close
#else
#define debuglog_close(...)
#endif
#define DEBUGLOG_LOG(level, fmt, ...) DEBUGLOG_LOG ## level (fmt, ##__VA_ARGS__)
#if DEBUG == 0
#define DEBUGLOG_LOG0(...)
#endif
#if DEBUG >= 1
#define DEBUGLOG_LOG1(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG1(...)
#endif
#if DEBUG >= 2
#define DEBUGLOG_LOG2(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG2(...)
#endif
#if DEBUG == 3
#define DEBUGLOG_LOG3(fmt, ...) debuglog_log (fmt, ##__VA_ARGS__)
#else
#define DEBUGLOG_LOG3(...)
#endif
void debuglog_init(char *filename);
void debuglog_close(void);
void debuglog_log(char* format, ...);
DebugLog.cpp:
// FILE: DebugLog.h
// REMARKS: This is a generic pair of files useful for debugging. It provides three levels of
// debug logging, currently; in addition to disabling it. See DebugLog.h's remarks for more
// info.
#include <stdio.h>
#include <stdarg.h>
#include "DebugLog.h"
FILE *hndl;
char *savedFilename;
void debuglog_init(char *filename)
{
savedFilename = filename;
hndl = fopen(savedFilename, "wt");
fclose(hndl);
}
void debuglog_close(void)
{
//fclose(hndl);
}
void debuglog_log(char* format, ...)
{
hndl = fopen(savedFilename,"at");
va_list argptr;
va_start(argptr, format);
vfprintf(hndl, format, argptr);
va_end(argptr);
fputc('\n',hndl);
fclose(hndl);
}
Using the macros
To use it, just do:
DEBUGLOG_INIT("afile.log");
To write to the log file, just do:
DEBUGLOG_LOG(1, "the value is: %d", anint);
To close it, you do:
DEBUGLOG_CLOSE();
although currently this isn't even necessary, technically speaking, as it does nothing. I'm still using the CLOSE right now, however, in case I change my mind about how it works, and want to leave the file open between logging statements.
Then, when you want to turn on debug printing, just edit the first #define in the header file to say, e.g.
#define DEBUG 1
To have logging statements compile to nothing, do
#define DEBUG 0
If you need info from a frequently executed piece of code (i.e. a high level of detail), you may want to write:
DEBUGLOG_LOG(3, "the value is: %d", anint);
If you define DEBUG to be 3, logging levels 1, 2 & 3 compile. If you set it to 2, you get logging levels 1 & 2. If you set it to 1, you only get logging level 1 statements.
As to the do-while loop, since this evaluates to either a single function or nothing, instead of an if statement, the loop is not needed. OK, castigate me for using C instead of C++ IO (and Qt's QString::arg() is a safer way of formatting variables when in Qt, too — it's pretty slick, but takes more code and the formatting documentation isn't as organized as it might be - but still I've found cases where its preferable), but you can put whatever code in the .cpp file you want. It also might be a class, but then you would need to instantiate it and keep up with it, or do a new() and store it. This way, you just drop the #include, init and optionally close statements into your source, and you are ready to begin using it. It would make a fine class, however, if you are so inclined.
I'd previously seen a lot of solutions, but none suited my criteria as well as this one.
It can be extended to do as many levels as you like.
It compiles to nothing if not printing.
It centralizes IO in one easy-to-edit place.
It's flexible, using printf formatting.
Again, it does not slow down debug runs, whereas always-compiling debug prints are always executed in debug mode. If you are doing computer science, and not easier to write information processing, you may find yourself running a CPU-consuming simulator, to see e.g. where the debugger stops it with an index out of range for a vector. These run extra-slowly in debug mode already. The mandatory execution of hundreds of debug prints will necessarily slow such runs down even further. For me, such runs are not uncommon.
Not terribly significant, but in addition:
It requires no hack to print without arguments (e.g. DEBUGLOG_LOG(3, "got here!");); thus allowing you to use, e.g. Qt's safer .arg() formatting. It works on MSVC, and thus, probably gcc. It uses ## in the #defines, which is non-standard, as Leffler points out, but is widely supported. (You can recode it not to use ## if necessary, but you will have to use a hack such as he provides.)
Warning: If you forget to provide the logging level argument, MSVC unhelpfully claims the identifier is not defined.
You might want to use a preprocessor symbol name other than DEBUG, as some source also defines that symbol (eg. progs using ./configure commands to prepare for building). It seemed natural to me when I developed it. I developed it in an application where the DLL is being used by something else, and it's more convent to send log prints to a file; but changing it to vprintf() would work fine, too.
I hope this saves many of you grief about figuring out the best way to do debug logging; or shows you one you might prefer. I've half-heartedly been trying to figure this one out for decades. Works in MSVC 2012 & 2015, and thus probably on gcc; as well as probably working on many others, but I haven't tested it on them.
I mean to make a streaming version of this one day, too.
Note: Thanks go to Leffler, who has cordially helped me format my message better for StackOverflow.
#define PRINT_LOG(str_format, ...) { \
time_t curtime=time (NULL); \
struct tm *ltm = localtime (&curtime); \
printf("[%d-%02d-%02d %02d:%02d:%02d] " str_format, \
ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, \
ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ##__VA_ARGS__); \
}
PRINT_LOG("[%d] Serving client, str=%s, number=%d\n", getpid(), "my str", 10);
I believe this variation of the theme gives debug categories without the need to have a separate macro name per category.
I used this variation in an Arduino project where program space is limited to 32K and dynamic memory is limited to 2K. The addition of debug statements and trace debug strings quickly uses up space. So it is essential to be able to limit the debug trace that is included at compile time to the minimum necessary each time the code is built.
debug.h
#ifndef DEBUG_H
#define DEBUG_H
#define PRINT(DEBUG_CATEGORY, VALUE) do { if (DEBUG_CATEGORY & DEBUG_MASK) Serial.print(VALUE);} while (0);
#endif
calling .cpp file
#define DEBUG_MASK 0x06
#include "Debug.h"
...
PRINT(4, "Time out error,\t");
...
If you don't care that the output goes to stdout, you can use this:
int doDebug = DEBUG; // Where DEBUG may be supplied in compiler command
#define trace if (doDebug) printf
trace("whatever %d, %i\n", arg1, arg2);

Resources