带有 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
的指针,只要它指向一个字符串,这种方法也适用。
这段代码片段:
#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
的指针,只要它指向一个字符串,这种方法也适用。