为什么我的简单C宏不起作用?
我想制作一个像这样调用printf()两次的简单宏
#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)
它正确打印第一部分“at sime_time = …”但后面的部分显示“已处理事件…”,错误地打印了id和数据的值。
与此同时
printf("Processed event type: %d with value %f\n", id, data);
正确打印值。
当我尝试通过写出我认为宏将评估的内容来执行它时,我有。
printf("At sim_time = %f:", sim_time); printf("Processed event type: %d with value %f\n", id, data);
这打印正确! 那么为什么我的宏不会对此进行评估呢?
因为您想要并且正在使用常规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)
封装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年以上。
但是,对于那些可能希望使用替代方法的人来说,这里有一些资源:
你声明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);
或者,如果您需要更灵活的东西,可以使用可变参数宏。
使用双(嵌套)定义:
#define FIRST printf("…") #define DEBUGMSG(msg) FIRST;printf(msg)
这在定义中有一个参数,在实现中有一个参数。