如何为 C 宏字符串化字符缓冲区

How to stringify char buffer for C macro

我有一个 LOG(fmt, ...) 宏,在将 char buf[] 用作 fmt 时不起作用。

下面的代码是代码的完整(实际上不是)工作示例。在 some_function() 中,我尝试以两种不同的方式使用 LOG(),但只有第一种方法有效。

为了解决这个问题,我试过按以下方式使用#define LOG_STR(x) #x

  1. 通过将 LOG_STR() 应用到 formatstringify#define LOG 中收到的内容,如下所示:LOG_STR(format);和

  2. 要将 LOG_STR() 直接应用于打印,如下所示:LOG(LOG_STR(fmt), 6).

这两种方法都行不通,事实上我从中得到了段错误。

    #include <stdio.h>

    #define LOG(format, ...) do {                             \
                fprintf(stderr, "[LOG] " format " [%s]\n",    \
                        ##__VA_ARGS__, __func__);             \
            } while (0)

    static void some_function()
    {
        // This works
        LOG("This is a number: %d", 5);

        // This does not work
        const char fmt[] = "This is a number: %d";
        LOG(fmt, 6);
    }

    int main(void)
    {
        some_function();
        return 0;
    }

当我编译上面的代码时,出现以下错误:

$ gcc -o log-macro-str log-macro-str.c
log-macro-str.c: In function ‘some_function’:
log-macro-str.c:15:6: error: expected ‘)’ before ‘fmt’
  LOG(fmt, 6);
      ^
log-macro-str.c:4:29: note: in definition of macro ‘LOG’
    fprintf(stderr, "[LOG] " format " [%s]\n",    \
                             ^~~~~~

我想像 some_function() 那样以两种方式使用 LOG() 或不使用修饰符而只打印一个字符串。我怀疑我可能必须对 format 部分进行字符串化,但我似乎无法正确地做到这一点。

我做错了什么,我该如何解决这个问题?

宏中的 stringify 运算符 # 将预处理器标记转换为字符串文字中的文本。它不会将 char 缓冲区的内容更改为编译时字符串文字。

要使您的宏起作用,请使用多个 fprintf 语句:

#define LOG(format, ...) do {                          \
            fprintf(stderr, "[LOG] ");                 \
            fprintf(stderr, format, __VA_ARGS__);      \
            fprintf(stderr, " [%s]\n", __func__);      \
        } while (0)