【问题标题】:Is it possible to stringify a variadic macro?是否可以对可变参数宏进行字符串化?
【发布时间】:2013-04-26 05:29:14
【问题描述】:
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 * 以对其执行一些额外的操作。

【问题讨论】:

  • double-hash 是连接操作符,而不是 stringify 操作符,它是单个哈希。
  • C99 中引入了可变参数宏
  • @JoachimPileborg:## 的使用是一个 GCC 扩展,如果 __VA_ARGS__ 列表为空,它会删除 ## 之前的逗号。 SO上有一个关于这个的问题;我在最近重读的一个答案中遇到了这个符号。 (一个外部参考是Macro definition;一个更好的是C #define macro for debug printing。)

标签: c macros


【解决方案1】:

嗯,不。预处理发生在甚至编译代码之前。它存在于与执行程序完全不同的宇宙中。您可以做的一件事是只运行预处理步骤并检查输出(使用 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;
}

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

【讨论】:

    猜你喜欢
    • 2014-12-15
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 2021-12-26
    相关资源
    最近更新 更多