28

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.

some_id
  • 29,466
  • 62
  • 182
  • 304
  • 4
    You use printf to print so debugging information and you want to "mute" them for the release ? Actually there is thousands of better practices to do this kind of things. – BenjaminB Apr 23 '11 at 16:06
  • 5
    Yeah. so mention a few please. – some_id Apr 23 '11 at 16:22
  • 1
    use assert(), use gdb, define a macro which print what you need for testing and empty it for the release (or comment its content) – BenjaminB Apr 23 '11 at 16:26
  • One can find an example here: http://msdn.microsoft.com/en-us/library/s6btaxcs%28v=vs.80%29.aspx –  Apr 26 '13 at 08:32
  • 1
    Leave the debug info in release build (or redirect stdout, or use a -verbose flag). You'll be glad you have them at the client's... – Alexandre C. Jun 28 '13 at 22:20
  • See also [C `#define` macro for debug printing](http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/1644898#1644898) which discusses some important issues closely related to this. – Jonathan Leffler Dec 22 '14 at 18:09

10 Answers10

27

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.

Alexander Gladysh
  • 39,865
  • 32
  • 103
  • 160
19
#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.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    This is assuming you do have `__VARARGS__` in your compiler. – Alexander Gladysh Apr 23 '11 at 15:52
  • 3
    @Alexander: I'm talking about the current (C99) standard - which does. – Jonathan Leffler Apr 23 '11 at 15:52
  • +1 I especially like the `(0)` that is good for things like `if (...) printf(...);`. However `-Wall` will warn `statement has no effect`. – julx Apr 23 '11 at 15:55
  • @Jonathan: But OP did not specify if he is using C99 or not. :-) – Alexander Gladysh Apr 23 '11 at 15:55
  • 7
    @Alexander: But C99 is the current C standard; if he wanted to use an old standard, or is working on a machine where the main native compiler is archaic, he should have said so. – Jonathan Leffler Apr 23 '11 at 15:58
  • @Julkiewicz: but by not writing '`((void)0)`', I ensure that code that does 'if (printf("Hi") <= 0)' continues to compile correctly. You can't have your cake and eat it, I think. You're right, in other words, but `printf()` is not always used in a void context. – Jonathan Leffler Apr 23 '11 at 15:59
9

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.

falstro
  • 34,597
  • 9
  • 72
  • 86
  • This is invalid and will result in major problems when you `#include `... – R.. GitHub STOP HELPING ICE Apr 23 '11 at 18:32
  • @R; which one are you referring to? I assume you mean defining printf, and you're right it'll break horribly if defined on the command line, or before stdio is included. Disregard that statement.. ;) If you're referring to the linking, then please elaborate.. – falstro Apr 23 '11 at 20:32
3

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.

user1284631
  • 4,446
  • 36
  • 61
3

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*, ...)
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
1

I included #define printf // in common header file. It will suppress all the printf.

Opal
  • 81,889
  • 28
  • 189
  • 210
1

Below simple function serves the purpose, I use the same.

int printf(const char *fmt, ...)
{
return (0)
}
1

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.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

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);
0

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.

gatoAlfa
  • 120
  • 4