试图创建一个宏,可以用于在定义debug时打印调试消息,就像下面的伪代码:
#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)
这是如何用宏来完成的呢?
试图创建一个宏,可以用于在定义debug时打印调试消息,就像下面的伪代码:
#define DEBUG 1
#define debug_print(args ...) if (DEBUG) fprintf(stderr, args)
这是如何用宏来完成的呢?
当前回答
#define debug_print(FMT, ARGS...) do { \
if (DEBUG) \
fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
} while (0)
其他回答
所以,当使用gcc时,我喜欢:
#define DBGI(expr) ({int g2rE3=expr; fprintf(stderr, "%s:%d:%s(): ""%s->%i\n", __FILE__, __LINE__, __func__, #expr, g2rE3); g2rE3;})
因为它可以插入到代码中。
假设您正在尝试调试
printf("%i\n", (1*2*3*4*5*6));
720
然后你可以把它改成:
printf("%i\n", DBGI(1*2*3*4*5*6));
hello.c:86:main(): 1*2*3*4*5*6->720
720
你可以得到一个表达式被求值为什么的分析。
这样就避免了双重评估的问题,但缺少物理系统确实会导致名称冲突。
然而它是嵌套的:
DBGI(printf("%i\n", DBGI(1*2*3*4*5*6)));
hello.c:86:main(): 1*2*3*4*5*6->720
720
hello.c:86:main(): printf("%i\n", DBGI(1*2*3*4*5*6))->4
所以我认为,只要避免使用g2rE3作为变量名,就可以了。
当然,我发现它(以及字符串的联合版本,以及调试级别的版本等)非常宝贵。
对于一个可移植的(ISO C90)实现,您可以使用双括号,就像这样;
#include <stdio.h>
#include <stdarg.h>
#ifndef NDEBUG
# define debug_print(msg) stderr_printf msg
#else
# define debug_print(msg) (void)0
#endif
void
stderr_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
int
main(int argc, char *argv[])
{
debug_print(("argv[0] is %s, argc is %d\n", argv[0], argc));
return 0;
}
或者(不推荐)
#include <stdio.h>
#define _ ,
#ifndef NDEBUG
# define debug_print(msg) fprintf(stderr, msg)
#else
# define debug_print(msg) (void)0
#endif
int
main(int argc, char *argv[])
{
debug_print("argv[0] is %s, argc is %d"_ argv[0] _ argc);
return 0;
}
#define debug_print(FMT, ARGS...) do { \
if (DEBUG) \
fprintf(stderr, "%s:%d " FMT "\n", __FUNCTION__, __LINE__, ## ARGS); \
} while (0)
如果你不关心输出到stdout,你可以使用这个:
int doDebug = DEBUG; // Where DEBUG may be supplied in compiler command
#define trace if (doDebug) printf
trace("whatever %d, %i\n", arg1, arg2);
#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);