【发布时间】:2017-05-23 16:30:46
【问题描述】:
我正在尝试编写一个 C 可变参数宏来检查它是使用一个参数还是多个参数调用的。
我发现了一些使用宏来计算参数的解决方案,但这些解决方案要么用于固定/有限数量的参数,要么依赖于共享相同类型的参数:
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
将参数计数到 10,然后失败。但是我认为检查 1 与多个参数是一个更容易的问题,因此它可能有一个适用于任何类型和任何数量参数的解决方案。
我对此的用途是一种debug_log 宏:
#define debug_log(...) \
do { \
fprintf(verbose, " - %lu ", time(NULL)); \
if (VA_HAS_MANY_ARGS(__VA_ARGS__)) { \
fprintf(verbose, __VA_ARGS__); \
} else {
fprintf(verbose, "%s\n", __VA_ARGS__); \
} \
while (0)
可以调用debug_log("string here");,也可以调用debug_log("string there %i\n", 5);,并将生成:
- current_time_here string here\n
- current_time_there string there 5\n
分别。
【问题讨论】:
-
对于导致this细节不使用完全不使用可变参数宏的问题可能有更好的解决方案...
-
看起来像 XCY 问题。您尝试解决的实际问题是什么?不要太喜欢宏!
-
@Olaf 我有一个调试宏,例如:
#define debug_log(...) do { fprintf(verbose, " - %lu %s\n", time(NULL), __VA_ARGS__); } while(0)工作正常,但缺少可变参数。我想要的是一个宏,我可以用debug_log("whatever string");和debug_log("whatever format string %i\n", 5);调用它,它会分别产生:“-current_time_here 任何字符串\n”、“-current_time_here 任何格式字符串5\n”。 -
听起来很糟糕而且容易出错。是什么让您无法使用两个不同的宏?
-
“但是我认为检查 1 和多个参数是一个更容易的问题” ...好奇...如果你知道如何做 A,但你不知道如何做 B,那么您基于什么推测 B 比 A 容易?
标签: c-preprocessor variadic-macros