变元论证宏

Version >= C99

具有可变参数的宏:

假设你要创建一些用于调试代码的 print-macro,我们以此宏为例:

#define debug_print(msg) printf("%s:%d %s", __FILE__, __LINE__, msg)

一些使用示例:

函数 somefunc() 如果失败则返回 -1,如果成功则返回 0,并且从代码中的许多不同位置调用它:

int retVal = somefunc();

if(retVal == -1)
{
    debug_printf("somefunc() has failed");
}

/* some other code */

 retVal = somefunc();

if(retVal == -1)
{
    debug_printf("somefunc() has failed");
}

如果 somefunc() 的实现发生变化会发生什么,现在它会返回与不同可能的错误类型匹配的不同值?你仍然希望使用调试宏并打印错误值。

debug_printf(retVal);      /* this would obviously fail */
debug_printf("%d",retVal); /* this would also fail */

为了解决这个问题,引入了 __VA_ARGS__ 宏。这个宏允许多个参数 X-macro:

例:

 #define debug_print(msg, ...) printf(msg, __VA_ARGS__) \
                               printf("\nError occurred in file:line (%s:%d)\n", __FILE__, __LINE)

用法:

int retVal = somefunc();

debug_print("retVal of somefunc() is-> %d", retVal);

此宏允许你传递多个参数并打印它们,但现在它禁止你发送任何参数。

debug_print("Hey");

这会引起一些语法错误,因为宏期望至少再有一个参数,并且预处理器不会忽略 debug_print() 宏中缺少逗号。此外 debug_print("Hey",); 会引发语法错误,因为你无法将参数传递给宏为空。

为了解决这个问题,引入了 ##__VA_ARGS__ 宏,该宏指出如果不存在变量参数,则预处理器从代码中删除逗号。

例:

 #define debug_print(msg, ...) printf(msg, ##__VA_ARGS__) \
                               printf("\nError occured in file:line (%s:%d)\n", __FILE__, __LINE)

用法:

 debug_print("Ret val of somefunc()?");
 debug_print("%d",somefunc());