使用类似函数的宏编译错误

时间:2012-12-24 10:51:36

标签: c macros

gcc 4.7.2     C89

您好,

我正在进行一些维护,我有以下类似函数的宏:

#define GET_ERROR() ((errno == 0) ? "None" : strerror(errno))

#define LOG_ERR(fmt, ...)                                               \
    fprintf(stderr, "[ERROR] %s:%d: error [%s] " fmt "\n", __func__, __LINE__, GET_ERROR(), ##__VA_ARGS__)

#define LOG_ASSERT(ARG, fmt, ...) do {                          \
        if(!(ARG)) {                                            \
            char arg_fmt[512];                                  \
            snprintf(arg_fmt, sizeof arg_fmt, "%s, ", #ARG);    \
            strcat(arg_fmt, fmt);                               \
            LOG_ERR(arg_fmt, ##__VA_ARGS__);                    \
            errno = 0;                                          \
            abort();                                            \
        }                                                       \
    } while(0)

LOG_ASSERT将模拟断言功能。但是会包含来自strerror errno的一些额外信息。

我正在使用的是这样的:

LOG_ASSERT(msg_id != -1, "Failed to connect to the message queue [ %d ]", msg_id);

所以它应该显示如下:

"msg_id != -1, Failed to connect to the message queue [ -1 ]"

我使用strcat在fmt的开头加上了“msg_id!= -1”。

但是,我得到了这些我似乎无法解决的编译错误。我认为这很简单,如果我遗漏了一些简单的东西,我只想得到另一个想法。

error: expected ‘)’ before ‘arg_fmt’
warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat]
warning: format ‘%d’ expects a matching ‘int’ argument [-Wformat]
warning: format ‘%s’ expects a matching ‘char *’ argument [-Wformat]

我知道有些人可能不同意这个宏,但这是我必须要维护的。

非常感谢任何建议

1 个答案:

答案 0 :(得分:4)

据我所知,你只能连接常量字符串文字,而不是char数组,这是你的问题:

fprintf(stderr, "[ERROR] %s:%d: error [%s] " fmt "\n", __func__, ....

fmt是一个字符数组,您需要另一个缓冲区来复制格式,或者您可以拆分printf

#define LOG_ERR(fmt, ...)                                               \
    fprintf(stderr, "[ERROR] %s:%d: error [%s] ", __func__, __LINE__, GET_ERROR());\
    fprintf(stderr, fmt, ##__VA_ARGS__)