C调试宏的奇怪语法

The strange syntax of a C debug macro

谁能给我解释一下下面的 C 语法(来自 tutorial)?我知道这是 C 的宏,但是 "DEBUG %s:%d: " M "\n"
部分对我来说很奇怪:为什么格式部分中间有宏参数'M'?

#define debug(M, ...) fprintf(stderr, 
            "DEBUG %s:%d: " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)

字符串在 C 中自动连接在一起。"Hello " "World!" 与 "Hello World!" 相同。

DEBUG("An error occurred opening file %s", filename) 

扩展为:

fprintf(stderr, "DEBUG %s:%d:  An error occurred opening file %s\n", __FILE__, __LINE__, filename)

我想你会同意这是非常方便和正确的结果。

debug("This should never happen!");

评估为

fprintf(stderr, "DEBUG %s:%d: " "This should never happen!" "\n", __FILE__, __LINE__, ##__VA_ARGS__)

连接到...

fprintf(stderr, "DEBUG %s:%d: This should never happen!\n", __FILE__, __LINE__, ##__VA_ARGS__)

所以它会打印类似...

DEBUG foo.c:51: This should never happen!

C 有一个有趣的怪癖,它连接字符串文字。如果你输入

"DEBUG %s:%d: " "HELLO %s!" "\n"

然后编译器将其视为一个字符串:"DEBUG %s:%d: HELLO %s!\n"。所以用户可以像使用 printf 参数一样使用这个宏:

debug("HELLO %s", username); //on line 94 of myfile.cpp

并且宏会自动添加文件名和行号。这种格式很有用,因为它可以帮助您了解 哪个 调试语句正在记录信息。

DEBUG myfile.cpp:94: HELLO zell