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 gc开发者_运维知识库c, 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.
精彩评论