##:如果参数不存在则忽略逗号和参数
...:可变参数
栗子:
#define Debug(fmt, args...) LOG("DEBUG", fmt, ##args)
-
...:
...
是C和C++预处理器中的一个特殊标记,用于表示一个可变数量的参数。- 在宏定义中,可以使用
...
来表示宏可以接受任意数量的参数。 - 在宏体内部,可以使用
__VA_ARGS__
(注意是两个下划线)来引用这些参数。但在上面的例子中,实际上使用了args...
作为参数名,并在宏体内部直接使用了args
。这是可以的,只要在宏体内部正确地引用了这些参数。
-
##args:
##
是C和C++预处理器中的另一个特殊标记,称为“参数连接符”(token-pasting operator)。- 当宏的参数列表中包含可变参数,并且希望在某些情况下忽略这些参数时(例如,当这些参数没有被实际提供时),
##
是非常有用的。 - 在上面的例子中,
##args
的作用是:如果args
为空(即没有提供额外的参数),则预处理器会忽略,
和args
,从而避免在编译时产生语法错误。
考虑以下情况:
Debug("Hello"); // 宏展开为:LOG("DEBUG", "Hello")
Debug("Hello, %d", 5); // 宏展开为:LOG("DEBUG", "Hello, %d", 5)
在第一个例子中,因为 args
没有被提供,所以预处理器使用 ##args
来忽略 ,
和 args
,从而避免在 LOG
函数调用中产生多余的逗号。