试图创建一个宏,可以用于在定义debug时打印调试消息,就像下面的伪代码:

#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)

这是如何用宏来完成的呢?


当前回答

我使用的方法是这样的:

#ifdef DEBUG
 #define D if(1) 
#else
 #define D if(0) 
#endif

而我只是用D作为前缀:

D printf("x=%0.3f\n",x);

编译器看到调试代码,没有逗号的问题,它的工作无处不在。此外,当printf不够用时,比如当你必须转储一个数组或计算一些对程序本身是冗余的诊断值时,它也可以工作。

编辑:好的,它可能会产生一个问题,当附近有其他地方可以被这个注入的if拦截。下面是一个版本:

#ifdef DEBUG
 #define D 
#else
 #define D for(;0;)
#endif

其他回答

#define PRINT_LOG(str_format, ...) { \
    time_t curtime=time (NULL); \
    struct tm *ltm = localtime (&curtime); \
    printf("[%d-%02d-%02d %02d:%02d:%02d] " str_format, \
        ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, \
        ltm->tm_hour, ltm->tm_min, ltm->tm_sec, ##__VA_ARGS__); \
}
    
PRINT_LOG("[%d] Serving client, str=%s, number=%d\n", getpid(), "my str", 10);
#define debug_print(FMT, ARGS...) do { \
    if (DEBUG) \
        fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
    } while (0)

这是我所使用的:

#if DBG
#include <stdio.h>
#define DBGPRINT printf
#else
#define DBGPRINT(...) /**/  
#endif

即使没有额外的参数,它也具有正确处理printf的好处。在DBG ==0的情况下,即使是最笨的编译器也没有什么可考虑的,因此不会生成任何代码。

我相信这个主题的变化提供了调试类别,而不需要每个类别有一个单独的宏名称。

我在Arduino项目中使用了这个变体,其中程序空间限制为32K,动态内存限制为2K。添加调试语句和跟踪调试字符串很快就会占用空间。因此,在每次构建代码时,必须能够将编译时包含的调试跟踪限制在必要的最低限度。

debug.h

#ifndef DEBUG_H
#define DEBUG_H

#define PRINT(DEBUG_CATEGORY, VALUE)  do { if (DEBUG_CATEGORY & DEBUG_MASK) Serial.print(VALUE);} while (0);

#endif

调用.cpp文件

#define DEBUG_MASK 0x06
#include "Debug.h"

...
PRINT(4, "Time out error,\t");
...

如果你不关心输出到stdout,你可以使用这个:

int doDebug = DEBUG;  // Where DEBUG may be supplied in compiler command
#define trace if (doDebug) printf

trace("whatever %d, %i\n", arg1, arg2);