Proper way to print different debug messages in C?

2.5k views Asked by At

I need to print msg1 and msg2 for the same error when compiled with and without DEBUG flag. E.g.

      fprintf( stderr,
#ifdef DEBUG
                      "error msg1 %s",__FILE__
#else
                      "error msg2"
#endif
              );

or other way might be to pass these msg1 and msg2 to a function and print it using vfprintf(). Probably, The second method would have run time overhead. So, I am just wondering what could be better way of doing this?

E.g. A use case might be that the code need to be compiled with info and debug flags. info might be user related messages and debug for debugging purpose. Any suggestions?

3

There are 3 answers

6
Mouin On BEST ANSWER

Usualy the traces are used in the code to help debug it, so for example in your NULL pointer tests you can add smth like if (ptr==NULL) DEBUG("Entering Null pointer");. I'am just telling you that because i don't udrestand why you want use both msg1 and msg2.

For me i usually use a macro DEBUG and a global variable verbose :

#define DEBUG(...)\
if(verbose && SHOW_ERROR) {\
printf("Error : %s, %d",__FUNCTION__, __LINE__);\
printf(__VA_ARGS__);\
}\
else if (verbose && SHOW_WARNING) {\
printf("Warning : %s, %d",__FUNCTION__, __LINE__);\
printf(__VA_ARGS__);\
}

Example :

#include <stdio.h>

#define SHOW_ERROR 1
#define SHOW_WARNING 2

int verbose = 1; 
int main()
{
  DEBUG("THIS WILL SHOW ERROR MSG");
  verbose = 2;
  DEBUG("THIS WILL SHOW WARNING MSG");
}

Hope i help.

3
Sergey Kalinichenko On

An unconditional call to vfprintf does carry some additional overhead for packaging the extra parameter, a, for use with the variable-argument list function. Moreover, conditional compilation allows the compiler to notice that the call to fprintf in DEBUG mode does not pass parameters other than the format string, and replace it with fputs("error msg1", stderr)*

However, this overhead is tiny, and you are unlikely to notice any of it, because the writing happens unconditionally, and it is going to dominate the timing of the call.

* It is uncommon for DEBUG output to provide less details than the non-debug one; usually, it is the other way around.

3
Nimrod Morag On

Your debug flag is a preprocessor macro, so the error message will be chosen at compile time, is this the behavior that you want?

I would suggest a slightly different approach:

#define PRINT_INFO(msg1,msg2) if(dbg){fprintf(stderr,msg1);}\
                              else{fprintf(stderr,msg2);}

where the dbg flag can be turned on and off at run time

You can play around even more using variadic macros:

#define PRINT_INFO_VAR(msg1,msg2...) if(dbg){fprintf(stderr,msg1);}\
                                     else{fprintf(stderr,msg2);}

And for the example you gave it would look like this:

PRINT_INFO_VAR(msg1,msg2,a)