为什么我的简单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年以上。

但是,对于那些可能希望使用替代方法的人来说,这里有一些资源:

  1. https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
  2. https://en.wikipedia.org/wiki/Variadic_macro

你声明DEBUGPRINTF是一个参数,但是你传递了三个,所以当然它没有按照你的预期工作。

在第一个示例中, msg只是"Processed event type: %d with value %f\n" ,而您的第二个printf()调用只是为%d%f提取垃圾,因为您的宏从未告诉它任何关于iddata因此它们永远不会传递给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) 

这在定义中有一个参数,在实现中有一个参数。