我想创建一个像这样调用printf()两次的简单宏
width
现在我打电话
height
它打印第一部分"在sime_time = ..."正确,但后面的部分,它说"处理事件......"不正确地打印id和数据的值。
同时
#ifdef ENABLE_DEBUGPRINTF
#define DEBUGPRINTF(msg) printf("At sim_time = %f:", sim_time); printf(msg);
#else
#define DEBUGPRINTF(msg) //evalutes to nothing
#endif
正确打印值。
当我通过写出我认为宏会评估的内容来尝试执行它时,我有。
DEBUGPRINTF("Processed event type: %d with value %f\n", id, data)
这样可以正确打印所有内容!那么为什么我的宏不评估呢?
答案 0 :(得分:2)
你声明DEBUGPRINTF
是一个参数,但是你把它传递了三个,所以当然它没有按你期望的那样工作。
msg
仅为"Processed event type: %d with value %f\n"
,而您的第二次printf()
来电只是为%d
和%f
提取垃圾,因为您的宏永远不会告诉它有关id
或data
的任何内容,因此它们永远不会传递给printf()
。
你想要这样的东西:
#define DEBUGPRINTF(msg, id, data) printf("At sim_time = %f:", sim_time); printf(msg, id, data);
或者,如果您需要更灵活的东西,可以使用可变参数宏。
答案 1 :(得分:2)
因为您希望并且正在使用常规printf
的完全灵活性,所以您需要的是具有variadic
参数的宏:
#ifdef ENABLE_DEBUGPRINTF
#define DEBUGPRINTF(msg...) \
printf("At sim_time = %f:", sim_time); printf(msg);
#else
#define DEBUGPRINTF(msg...) /*evalutes to nothing*/
#endif
之前我已多次这样做,我建议使用do { } while (0)
进行封装:
#ifdef ENABLE_DEBUGPRINTF
#define DEBUGPRINTF(msg...) \
do { \
printf("At sim_time = %f:", sim_time); \
printf(msg); \
} while (0)
#else
#define DEBUGPRINTF(msg...) //evalutes to nothing
#endif
这允许您执行以下操作:
if (showit)
DEBUGPRINTF("hit the showit point -- showit=%d\n",showit);
因此,使用宏的代码不必知道它实际上是两个语句[或者没有]
<强>更新强>
DEBUGPRINTF(msg...)
不符合标准,但是一些遗留的编译器扩展。你在省略号之前错过了一个逗号。
或许,但是,就个人而言,我仍然更喜欢它,并且已经在生产代码中使用了10年以上。
但是,对于那些可能希望使用其他方式的人来说,这里有一些资源:
答案 2 :(得分:-3)
使用双(嵌套)定义:
#define FIRST printf("…")
#define DEBUGMSG(msg) FIRST;printf(msg)
这在定义中有一个参数,在实现中有一个参数。