如何编写扩展为`#ifdef ... #endif`宏块的C宏?

时间:2016-08-02 02:37:41

标签: c macros

我想将一些调试输出语句插入到一个大的C代码库中。这些调试输出语句将由编译器选项开关控制。

调试输出语句如下所示:

#ifdef DEBUG_FLAG
 Print(someSymbol)
#endif

为了保存一些输入,我想知道是否可以定义一个扩展到上面的调试输出语句块的简单宏?

例如:

#define DBG_MACRO(someSymbol)  (something that can expand to above)

3 个答案:

答案 0 :(得分:7)

您不能将预处理程序指令放在预处理程序宏中。

但是,没有什么可以阻止你定义一个扩展为空的宏:

#ifdef DEBUG_FLAG
#  define Print(x) Print(x)
#else
#  define Print(x)
#endif

// Expands to an empty statement if DEBUG_FLAG were not set and
// to a call to Print(something) if DEBUG_FLAG were set.
Print(something);

以上内容取决于Print是一个已经声明/定义的函数。如果使用DEBUG_FLAG set定义宏,则宏将自行“替换”,但C预处理器扩展不是递归的,因此扩展只发生一次,从而导致调用Print

答案 1 :(得分:5)

不可能这样做;但是,很容易有条件地定义一个宏:

#ifdef DEBUG_FLAG
    #define DBG_MACRO(arg) Print(arg)
#else
    #define DBG_MACRO(arg)
#endif

答案 2 :(得分:0)

最好制作一个可以处理许多调试语句的数据库宏。 然后,您可以使用以下4个字符快速包围所有可选的调试代码:DB() 这是宏:

#define DEBUG    true    // or false
#ifdef DEBUG
    #define DB(arg) { arg }
#else
    #define DB(arg)
#endif

//  Example uses:
DB(Serial.begin (9600);)

DB(if (!bLastRadarMotion)
   Serial.println("New Motion");)

DB(Serial.print("Room just became UN-Occupied after ");
Serial.print(stillSecondsThreshold);
Serial.println(" seconds.");)

DB(
Serial.print("Room just became UN-Occupied after ");
Serial.print(stillSecondsThreshold);
Serial.println(" seconds.");
)