如何扩展宏和删除逗号
How to expand macro and delete comma
例如我想编写自己的 printf() 替代方案,但我必须对变量参数执行计算:
#define log(fmt_string, ...) my_log(fmt_string, pack_args(__VA_ARGS__), __VA_ARGS__)
其中 pack_args(...) - 也是一个宏。
我应该如何更改此代码以处理唯一的 fmt_string 存在场景?
log("Some message here");
How should I change this code to [handle] the only fmt_string presence scenario?
您根本无法使用标准 C 中的可变参数宏执行此操作。该标准在可变参数宏的调用中明确指定 "there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...)" (C2011, 6.10.3/4)。您可以通过将宏更改为 ...
来允许宏仅与一个参数一起使用
#define log(...) /* ... */
...但是您无法将格式字符串与其他参数分开 - 至少在没有重新引入您现在遇到的相同问题的情况下无法分开。
如果需要支持零长度变量参数列表,则需要使用真正的函数。
在P99我有两个宏
#define P00_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, \
_9, _10, _11, _12, _13, _14, _15, _16, \
... etc ... \
_153, _154, _155, _156, _157, _158, _159, \
...) _159
#define P99_HAS_COMMA(...) P00_ARG(__VA_ARGS__, \
1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
... etc .... \
1, 1, 1, 1, 1, 1, 0, 0)
您可以使用它来确定您的参数是否有逗号(因此参数比您的格式多)或没有(只有一种格式)。然后您可以使用它来构造对两个宏之一的调用:
#define log(...) log2(P99_HAS_COMMA(__VA_ARGS__), __VA_ARGS__)
#define log2(N, ...) log3(N, __VA_ARGS__)
#define log3(N, ...) log ## N(__VA_ARGS__)
#define log0(FMT) /* your version with format only goes here */
#define log1(FMT, __VA_ARGS__) /* your version with more goes here */
例如我想编写自己的 printf() 替代方案,但我必须对变量参数执行计算:
#define log(fmt_string, ...) my_log(fmt_string, pack_args(__VA_ARGS__), __VA_ARGS__)
其中 pack_args(...) - 也是一个宏。 我应该如何更改此代码以处理唯一的 fmt_string 存在场景?
log("Some message here");
How should I change this code to [handle] the only fmt_string presence scenario?
您根本无法使用标准 C 中的可变参数宏执行此操作。该标准在可变参数宏的调用中明确指定 "there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...)" (C2011, 6.10.3/4)。您可以通过将宏更改为 ...
来允许宏仅与一个参数一起使用#define log(...) /* ... */
...但是您无法将格式字符串与其他参数分开 - 至少在没有重新引入您现在遇到的相同问题的情况下无法分开。
如果需要支持零长度变量参数列表,则需要使用真正的函数。
在P99我有两个宏
#define P00_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, \
_9, _10, _11, _12, _13, _14, _15, _16, \
... etc ... \
_153, _154, _155, _156, _157, _158, _159, \
...) _159
#define P99_HAS_COMMA(...) P00_ARG(__VA_ARGS__, \
1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
... etc .... \
1, 1, 1, 1, 1, 1, 0, 0)
您可以使用它来确定您的参数是否有逗号(因此参数比您的格式多)或没有(只有一种格式)。然后您可以使用它来构造对两个宏之一的调用:
#define log(...) log2(P99_HAS_COMMA(__VA_ARGS__), __VA_ARGS__)
#define log2(N, ...) log3(N, __VA_ARGS__)
#define log3(N, ...) log ## N(__VA_ARGS__)
#define log0(FMT) /* your version with format only goes here */
#define log1(FMT, __VA_ARGS__) /* your version with more goes here */