宏关闭printf语句

时间:2011-04-23 15:48:25

标签: c

可以使用什么MAC来关闭printf语句,而不是全部删除它们用于部署版本,我只想关闭它们,跳过它们,忽略它们。

编辑:我个人使用gcc,但代码是一个大型项目的一部分,它将在运行Ubuntu的Panda板上编译。

10 个答案:

答案 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);