1.用宏重新定义printf(debug)
可以这样定义宏:
#include <stdio.h>
//#define NDEBUG 10
#ifdef NDEBUG
#define debug_printf(fmt, ...)
#else
extern int debug_print;
#define debug_printf(fmt, ...) ({ \
if(debug_print) \
{ \
printf(fmt, ##__VA_ARGS__);\
} \
})
#endif
int main(void) {
int debug_print=1;
debug_printf("test%d",1,23);
return 0;
}
输出:
test1
当我们不想让main函数中的debug_printf生效,且不删除main函数中的debug_printf()时,那么就需要定义NDEBUG,如果不定义就会报如下函数没有定义的错误,如果定义了,那么根据#if NDEBUG下只定义宏名,没有宏函数体,展开时就没有东西,但编译不会报错。
#include <stdio.h>
//#define NDEBUG 1
#ifdef NDEBUG
#define debug_printf(fmt, ...)//只定义宏名,没有宏函数体,展开时就没有东西
#else
extern int debug_print;
#define debug_printf(fmt, ...) ({ \
if(debug_print) \
{ \
printf(fmt, ##__VA_ARGS__);\
} \
})
#endif
int main(void) {
//int debug_print=1;
debug_printf("test%d",1,23);
return 0;
}
输出:
Compilation Failed
/usr/bin/ld: /tmp/ccXdjenI.o: in function `main':
file.cpp:(.text+0x6): undefined reference to `debug_print'
collect2: error: ld returned 1 exit status
2.宏函数中的可变参数
#define debug_printf(fmt, ...) ({ \
if(debug_print) \
{ \
printf(fmt, __VA_ARGS__);\
} \
})
”…”表示可变参数。在宏的调用中,它会展开为…位置处传入的所有字符,数字,包括逗号,并替换掉宏体中的__VA_ARGS__,注意fmt, ##__VA_ARGS__之间的“,”也会展开。所以当没有参数传入时,比如
debug_printf(“hello world”)
上面会展开成:
{
if(debug_print)
{
printf("hello world",);
}
}
那么就多了一个“,”会报错。
所以就有了在__VA_ARGS__前加##,目的是,当省略可变参数时,”##”会使得预编译器删除它前面的逗号,提供可变参数时,”##”不起作用。
也可以指定可变参数名称:
#define debug_printf(fmt, chm...) ({ \
if(debug_print) \
{ \
printf(fmt, ##chm);\
} \
})
chm可以替换成其他。