我正在编译:
gcc 4.7.2
c89
我有macro:
#define LOG_ERR(fmt, ...) \
fprintf(stderr, "[ERROR] %s:%d: error [%s] " fmt "\n", __func__, __LINE__, strerror(errno), ##__VA_ARGS__)
我是这样使用它的:
LOG_ERR("Failed to connect to message queue [ %d ]", msg_id);
fmt
已在fprintf
语句中连接。这怎么可能?
我试着对下面的代码做同样的事情(只是为了测试这个概念),但是由于编译错误而失败:
/* Using char array */
const char name[] = "Joe";
printf("Hello how " name " how are you today?\n");
Using constant string literal
const char *name = "Joe";
printf("Hello how " name " how are you today?\n");
两者都给了我以下错误:
expected ')' before name
感谢您的任何建议!
5条答案
按热度按时间nzk0hqpo1#
您需要一个格式说明符,请查看documentation for printf
您的尝试:
看起来更像C++
kadbb4592#
当它失败时,那是因为你使用了变量。字符串字面量可以由编译器连接,即。如果你写“abc”“123”,那么编译器会把它当作“abc 123”。当你在宏中这样做的时候,预处理器意味着,这就是发送给编译器的内容
成为
可能也值得检查字符串化器和串联宏(对于预处理器-
#
和##
,我从来不记得哪个是哪个...)安德鲁
hwamh0ep3#
不同之处在于,宏将文字
fmt
替换为字符串。将两个或多个文字字符串放在一起可以得到这些字符串的连接。记住,只有literal字符串才能做到这一点。这个**不适用于变量。
把宏想象成代码中的find/replace。为了说明,考虑你的宏定义-
当你这样使用它-
它做了一个文本替换,变成了-
并排的字符串和连接,瞧-
41zrol4v4#
如果你想为
fprintf()
定义一个宏,你可以这样做,这是最简单的IMHO。然后用它来
hk8txs485#