可以使用什么MAC来关闭printf语句,而不是全部删除它们用于部署版本,我只想关闭它们,跳过它们,忽略它们。
编辑:我个人使用gcc,但代码是一个大型项目的一部分,它将在运行Ubuntu的Panda板上编译。答案 0 :(得分:22)
不完全是你要求的,但是当我没有合适的日志记录系统时,我在我的代码中使用这个构造进行调试输出:
#if 1
#define SPAM(a) printf a
#else
#define SPAM(a) (void)0
#endif
所以我可以在我的代码上做到这一点
SPAM(("foo: %d\n", 42));
然后将上述1
中的0
更改为#if
,停用所有这些内容。
但是如果你在编写代码的所有编译器中都有可变宏支持,那么你可以寻找其他答案并重新定义printf
。 (话虽如此,我发现在代码中从常规调试打印不同是有用的 - 使用不同的函数名称有助于提高可读性。)
请注意,您也可以将stdout
重定向到/dev/null
,但我认为您也希望摆脱运行时开销。
答案 1 :(得分:15)
#ifdef IGNORE_PRINTF
#define printf(fmt, ...) (0)
#endif
另见C #define macro for debug printing,其中讨论了与此密切相关的一些重要问题。
答案 2 :(得分:9)
两个选项:
#define printf(...)
(需要C99可变参数宏参数),你需要把它放在一些常见的头文件中,这个文件在stdio.h之前永远不会被包含,如果有的话......
或者您可以告诉链接器将其链接到其他内容,在GCC中您将定义
int wrap_printf(void) {return 0;}
并使用
链接--wrap printf
所有这一切,您可能不应该使用printf
来打印调试输出,而是使用宏或实用程序功能(如果您愿意,可以使用printf),您可以更好地控制它。
希望有所帮助。
答案 3 :(得分:3)
我使用PDEB作为调试printf()s(不是全部)的前缀。
对于调试版本,我使用-DPDEB =(nothing)
进行编译对于发布版本,我使用-DPDEB =“0&&”进行编译或-DPDEB =“0&&”
这样,下面的代码(test.c):
#include <stdio.h>
void main(void) {
printf("normal print\n");
PDEB printf("debug print\n");
}
输出: (在发布模式下): 正常打印
(在调试模式下): 正常打印 调试打印
理想情况下,可以将PDEB转换为“//”(注释标记),除非在标准预处理/处理链下不可能。
答案 4 :(得分:1)
如果您想避免Jonathan的回答可能给您的潜在警告,如果您不介意对printf
进行空话,您也可以执行类似
#define printf(...) printf("")
这是有效的,因为C宏不是递归的。展开的printf("")
将保留原样。
另一种变体(因为你使用的是gcc)就像是
inline int ignore_printf(char const*, ...)
__attribute__ ((format (printf, 1, 2)));
inline int ignore_printf(char const*, ...) { return 0; }
#define printf ignore_printf
并在一个编译单元中
int ignore_printf(char const*, ...)
答案 5 :(得分:0)
另一种可能性是freopen("/dev/null", "w", stdout);
这并不能完全禁用printf
- 它大致相当于使用stdout重定向到/ dev / null来运行程序,例如:./myprog > /dev/null
在shell提示符下。
答案 6 :(得分:0)
我为此使用了两个宏。第一个定义要打印的条件。在这个简单的例子中,我们在参数不为零的任何时候打印。可以使用更复杂的表达式。
第二个基于第一个宏确定是否调用printf。
如果条件可以由编译器确定(使用正确的优化设置),则不会生成代码。
如果在编译时无法确定条件,那么将在运行时。这种方法的一个优点是,如果printf不会发生,那么整个printf就不会被评估,从而避免在复杂的printf语句中发生很多字符串转换。
#define need_to_print(flag) ((flag) != 0)) #define my_printf(debug_level, ...) \ ({ \ if(need_to_print(debug_level)) \ printf(__VA_ARGS__); \ })
使用它来调用 my_printf 而不是 printf ,并在打印条件的开头添加一个参数。
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
围绕宏的(...)括号使它成为单个语句。
答案 7 :(得分:0)
我在公共头文件中包含了#define printf
//。它将取消所有printf
。
答案 8 :(得分:0)
下面简单的功能是出于此目的,我使用相同的。
int printf(const char *fmt, ...)
{
return (0)
}
答案 9 :(得分:0)
使用此宏可以启用或禁用打印功能。
//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
然后调用“ DEBUG_PRINTF”而不是“ printf”。
例如:
DEBUG_PRINTF("Hello world: %d", whateverCount);