我在尝试将宏常量作为参数传递给宏函数时遇到问题。

考虑以下代码-

#define ERROR 10
#define MAIN "Main:"

#define LOG(lvl,mod,fmt,...) \
    char msg[256] = {0}; \
    snprintf(msg, 256, "%s: %d: "fmt,mod,lvl,##__VA_ARGS__)

int main()
{   ....
    LOG(ERROR, MAIN, "This is a log statement.\n"); // Doesn't compile
    LOG(10, "Main:", "This is a log statement.\n"); // Compiles
    ....
}


第二条日志语句会编译,但第一条日志语句会生成以下编译错误-

error: expected `)' before ‘;’ token
error: expected primary-expression before ‘,’ token
error: expected `;' before ‘)’ token


为什么会这样呢?我希望能够定义一组日志记录级别和模块常量,并在调用LOG()宏时使用它们。

最佳答案

宏的一个问题是,它在代码块的随机位置声明了一个变量,C89不允许这样做:只允许您在块的顶部声明变量。即使使用C99编译器,问题也不会消失,因为现在您可以在同一作用域中引入多个具有相同名称的声明,这是禁止的。

您可以使用do/while(0) trick解决此问题:

#define LOG(lvl,mod,fmt,...) do {\
    char msg[256] = {0}; \
    snprintf(msg, 256, "%s: %d: "fmt,mod,lvl,##__VA_ARGS__) \
} while(0)

关于c - 以其他宏作为参数调用C宏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42228623/

10-11 15:34