Øyv*_*eig 6 c printf c-preprocessor variadic-macros
我发现无法将第一个 printf 合并到第二个:
unsigned get_time_now(void) {return 1;}
#define DEBUG_PRINT 1
#define debug_tcprintf(fmt, ...) do { \
if (DEBUG_PRINT) { \
unsigned p_time_now = get_time_now(); \
printf ("%u ms ", p_time_now); \
printf(fmt, __VA_ARGS__); \
} \
} while (0)
Run Code Online (Sandbox Code Playgroud)
我需要完成此操作才能获得原子 debug_tcprintf。上面的宏取自这个 Stack Overflow 问题。
我正在 XC 中编写在 XMOS 多逻辑核心处理器上运行的代码。它编译 XC、C 和 C++,但代码示例来自 C 代码部分。除了它有一个用语言定义的计时器之外,它与 XC 类似。
如果不可能将两者合并到一个 printf 中,一个选项可能是创建一个字符串并使用 sprintf 代替?我宁愿不这样做,因为这样的数组可能很容易溢出。
您需要使用字符串连接和标记粘贴。请注意,在下面的代码片段中,第一个字符串文字后面没有逗号——这是故意的。
#define debug_tcprintf(fmt, ...) do { \
if (DEBUG_PRINT_HTTPD) { \
unsigned p_time_now = get_time_now (); \
printf ("%u ms " fmt, p_time_now, ##__VA_ARGS__); \
} \
} while (0)
Run Code Online (Sandbox Code Playgroud)
字符串连接允许您将该"%u ms "
部分附加到提供的格式字符串上。令牌粘贴(##
运算符)说明了使用或不使用附加可变参数(除了格式字符串之外)调用宏的可能性。
仅当您使用字符串文字作为格式字符串调用宏时,这才有效。
附录:本例中使用的标记粘贴方式实际上是标准 C 预处理器的 gcc 扩展。如果您不使用 gcc 编译器,则可能需要省略该##
运算符。这样做的缺点是您无法仅使用一个参数来调用宏;例如,debug_tcprintf ("hello world")
将不起作用。debug_tcprintf ("%s", "hello world")
一个简单的解决方法是在这种情况下使用。