ant2009
ant2009

Reputation: 22486

compile error with function-like macro

gcc 4.7.2 c89

Hello,

I am working on some maintainance and I have the following function-like macros:

#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)

The LOG_ASSERT will simulate an assert function. But will contain some extra information from the strerror errno.

Which I am using like this:

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

So it should display like this:

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

I have prefixed the "msg_id != -1" at the beginning of the fmt using strcat.

However, I get these compile errors that I cannot seem to fix. I thought it was something easy, and just want to get another idea if I am missing something simple.

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]

I know that some people might not agree with this macros, but this is what I have to maintain.

Many thanks for any suggestion

Upvotes: 3

Views: 773

Answers (1)

iabdalkader
iabdalkader

Reputation: 17312

As far as I know you can only concatenate constant string literals, not char arrays, here's your problem:

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

fmt is a character array, you will need another buffer to copy the format or you could just split the printf

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

Upvotes: 4

Related Questions