是否可以对可变参数宏进行字符串化?

时间:2013-04-26 05:29:14

标签: c macros

gcc (GCC) 4.7.2
c89

是否可以对可变参数宏进行字符串化?

我有以下宏,我想从fmt和参数输出结果字符串。

#define ERROR_MESSAGE(priority, fmt, ...)        \
    do {                                         \
        MODULE_LOG(priority, fmt, ##__VA_ARGS__);\
} while(0)

所以,我只想获得fmt##__VA_ARGS__的完整字符串,以便我可以将其分配给char *以对其执行一些额外的操作。

1 个答案:

答案 0 :(得分:5)

嗯,不。预处理在代码编译之前发生。它存在于与执行程序完全不同的世界中。您可以做的一件事是,只运行预处理步骤并检查输出(使用gcc开关-E来打印预处理器输出)。

您可以做的最多是将其重定向到文件,然后在程序中读取该文件。


进一步思考,让我从“不”退缩,并将其改为“也许”。看一下this other answer of mine,它为可变参数宏实现了一个“foreach”宏。

因此,使用APPLYXn(以及隐式地,PPNARG),您可以将STR(x) #x宏应用于这样的args(如编写的那样,APPLYXn可以处理最多15个参数):

#define X(x) #x
#define ERROR_MESSAGE(priority, fmt, ...)        \
    "do {MODULE_LOG(" X(priority) X(fmt) APPLYXn(__VA_ARGS__) ");} while(0)"

int main() {
    printf("%s\n", ERROR_MESSAGE(3, "%d", 5) );
    return 0;
}

gcc -E生成

# 1 "strvar.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "strvar.c"
# 71 "strvar.c"

int main() {
    printf("%s\n", "do {MODULE_LOG(" "3" "\"%d\"" "5" ");} while(0)" );
    return 0;
}

编译器会将所有这些字符串文字连接成一个字符串。