使用宏
如果您想使用一个宏,将对dbg_out 的调用更改为对printf 的直接调用,您可以使用可变参数宏:
#define dbg_out(mask, ...) printf(__VA_ARGS__)
int main() {
dbg_out(1, "%d", 12);
}
如果他们在你的问题中被称为双括号(例如dbg_out((5, "%d", 12));
),那么你需要先解包:
#define EXPAND(mask, ...) (__VA_ARGS__)
#define dbg_out(...) printf EXPAND __VA_ARGS__
int main() {
dbg_out((1, "%d", 12));
}
此外,如果您知道格式始终为字符串文字,您还可以将掩码添加到 printf 输出,例如:
#define dbg_out(mask, format, ...) printf("[Mask:%d]" format, mask, ##__VA_ARGS__)
int main() {
dbg_out(1, "%d", 12);
}
双括号调用:
#define EXPAND(mask, format, ...) ("[Mask:%d]" format, mask, ##__VA_ARGS__)
#define dbg_out(...) printf EXPAND __VA_ARGS__
int main() {
dbg_out((1, "%d", 12));
}
使用宏重定向到另一个函数
如果您无法更改 dbg_out 的实现,您可以使用宏将调用重定向到另一个执行该工作的函数:
#include <stdarg.h>
#define dbg_out(...) dbg_out_new(__VA_ARGS__)
void dbg_out_new(int mask, const char* fmt, ...) __attribute__((format(printf, 2, 3)));
void dbg_out_new(int mask, const char* fmt, ...) {
va_list va;
va_start(va, fmt);
vprintf(fmt, va);
va_end(va);
}
int main() {
dbg_out(1, "%d", 12);
}
如果用双括号调用,需要把宏改成:
#define dbg_out(...) dbg_out_new __VA_ARGS__
/* ... */
int main() {
dbg_out((1, "%d", 12));
}
使用__attribute__(format()),您还可以获得参数的编译时类型检查的好处,就像在“使用宏”示例中一样。
改变功能
如果您可以编辑 dbg_out 函数实现,则可以将其替换为上述 dbg_out_new 实现。
但是,如果像您在问题中写的那样用双括号调用它,这将不起作用。