我发现无法将第一个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)
我需要完成这个以获得原子debug_tcprintf。上面的宏取自this Stack Overflow question。
我正在XC中运行在XMOS多逻辑核心处理器上运行的代码。它编译XC,C和C ++,但代码示例来自C代码部分。它与XC类似,只是它有一个用语言定义的计时器。
如果无法将二者合并为一个printf,那么选项可能是创建字符串并使用sprintf代替?我不愿意,因为这样的数组可能很容易溢出。
答案 0 :(得分:1)
您需要使用字符串连接和token pasting。请注意,在下面的代码段中,第一个字符串文字后面没有逗号 - 这是故意的。
#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)
字符串连接允许您将"%u ms "
部分添加到提供的格式字符串上。令牌粘贴(##
运算符)说明了在使用或不使用其他可变参数的情况下调用宏的可能性(超出格式字符串)。
仅当您使用字符串文字作为格式字符串调用宏时才有效。
附录:此示例中使用令牌粘贴的方式实际上是标准C预处理器的gcc扩展。如果您不使用gcc编译器,则可能需要省略##
运算符。这样做的缺点是你不能只用一个参数调用你的宏;例如,debug_tcprintf ("hello world")
将无效。一个简单的解决方法是在这种情况下使用debug_tcprintf ("%s", "hello world")
。