带有 fprintf 字符串的宏函数

Macro function with string of fprintf

这段代码片段:

#define ERROR_MSG_DETAIL(msg_str) \
   fprintf(stderr, (msg_str) "%s\n, at # %d, file: %s\n", strerror(errno), __LINE__, __FILE__) 

我希望我只是输入错误信息

ERROR_MSG_DETAIL("my errors")

宏应该扩展到

fprintf(stderr, "my errors" "%s\n, at # %d, file: %s\n", strerror(errno), __LINE__, __FILE__) 

结果应如下所示:

my errors
at # 15, file: t.c

但是我在编译时收到了这个错误信息

 error: expected ‘)’ before string constant
   11 |  fprintf(stderr, (msg_str) "%s\n, at # %d, file: %s\n", strerror(errno), __LINE__, __FILE__)
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~

如何解决?

如果它们之间没有括号,您只能连接字符串文字,因此您应该更改您的宏,删除 msg_str:

周围的括号
#define ERROR_MSG_DETAIL(msg_str) \
   fprintf(stderr, msg_str ": %s\n, at # %d, file: %s\n", strerror(errno), __LINE__, __FILE__)

更好的方法是像这样定义宏:

#define ERROR_MSG_DETAIL(msg_str) \
    fprintf(stderr, "%s%s\n, at # %d, file: %s\n", (msg_str), strerror(errno), __LINE__, __FILE__)

如果由 msg_str 表示的字符串包含 % 字符,您的方法(即使它在语法上是正确的)也会导致未定义的行为,这意味着 fprintf 将尝试解释该字符。上述方法适用于每个字符串,与包含的字符无关。顺便说一句, msg_str 不一定是字符串文字;如果 msg_str 是指向 char 的指针,只要它指向一个字符串,这种方法也适用。