tags:

views:

178

answers:

5

For debugging purposes I would like to have a printf_debug function that would function just like the standard printf function, but would only print if a #DEFINE DEBUG was true

I know I have to use varagrs (...) but I have no idea how to actually achieve that.

Thanks in advance.

A: 

I don't what exactly you want to achieve. In case you want a code block to execute only if DEBUG is defined, use the preprocessor directive #ifdef.

#include <stdio.h>
#include <stdarg.h>
#define DEBUG

void printf_debug(const char *format, ...) {
  #ifdef DEBUG
  va_list args;
  va_start(args, format);
  vprintf(format, args);
  va_end(args);
  #endif /* DEBUG */
}
Propeng
I know that's the "idea" for the function, but that code doesn't actully compiles. Would you mind providing a working function? Thanks.
nunos
The #ifdef will always be true. The arguments to printf_debug aren't valid (a ... can only follow a real argument). The arguments aren't passed to printf. There's a missing semicolon after the printf statement. The printf is commented out. It's commented out with // which is not standard C.
Paul Hankin
I know, I was demonstrating the use of #ifdef. I'll edit this in a minute.
Propeng
`//` has been part of C since last century: http://en.wikipedia.org/wiki/C99
Ken
+1  A: 

You have to use the va_arg macros, they are used to access the variadic variables. A useful link: http://www.cppreference.com/wiki/c/other/va_arg. The reference is for C++, but these macros can be used in C as well.

In your actual implementation you place the code using the variadic variables in a #ifdef block.

But if you're looking for a regular call to printf, dependent on DEBUG a simple #define acting as an alias will do.

Pieter
Upvoted, but you should mention #include <stdarg.h>, since the reference you gave uses the C++ version <cstdarg>
Paul Hankin
The link refers to functions but i think nunos wanted an answer in regard to macros. In which case varidic macros were only added in C99.
Gary Willoughby
+8  A: 

Easier to just #define it away. Something like this:

#ifdef DEBUG
#define printf_debug printf
#else
#define printf_debug while(0)printf
#endif
Paul Hankin
Didn't remember that. That's a useful answer, however, I would like to know how to achieve what I asked with varargs. Thanks anyway. Vote up.
nunos
+1. Nice and simple. Why reinvent the wheel?
Platinum Azure
why is there a 'printf' after 'while(0)'?
Gary Willoughby
@Gary - if there wasn't, you'd get a syntax error when compiling in non-debug mode because of the arguments being passed to printf
Eric Petroelje
I get no syntax error without it, using a C99 compiler.
Gary Willoughby
hmmm... maybe it's being optimised away? i've tried it with ints as well as strings, still no error.
Gary Willoughby
Yes, amusingly you don't need the printf... it turns into an expression using the comma operator.
Paul Hankin
+1  A: 

You don't need to use vargs, macros will work. Here is an example, which will prints function and line number as well:

#ifdef DEBUG
#define printf_debug(fmt, args...) printf("%s[%d]: "fmt, __FUNCTION__, __LINE__, ##args)
#else
#define printf_debug(fmt, args...)
#endif

The ##args here will be replaced by the args list, which likes what vargs does in function call.

ZelluX
A: 

C99 compiler only!

#include <stdio.h>

#define DEBUG

#ifdef DEBUG
 #define debug(...) printf(__VA_ARGS__)
#else
 #define debug while(0)
#endif

int main(int argc, char *argv[])
{
    debug("Only shows when DEBUG is defined!\n");
    return 0;
}

to be honest varidic macros are not needed you could just easily write it as this:

#include <stdio.h>

#define DEBUG

#ifdef DEBUG
 #define debug printf
#else
 #define debug while(0)
#endif

int main(int argc, char *argv[])
{
    debug("Only shows when DEBUG is defined!\n");
    return 0;
}

Thinking about it, debug information should go to stderr so as not to interfer with stdout, so this one should be favoured:

#include <stdio.h>

#define DEBUG

#ifdef DEBUG
 #define debug(...) fprintf(stderr, __VA_ARGS__)
#else
 #define debug while(0)
#endif

int main(int argc, char *argv[])
{
    debug("Only shows when DEBUG is defined!\n");
    return 0;
}
Gary Willoughby