【问题标题】:How to stringify char buffer for C macro如何为 C 宏字符串化字符缓冲区
【发布时间】:2019-01-24 19:18:46
【问题描述】:

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

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

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

  1. 通过将LOG_STR() 应用于format字符串化 #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 部分进行字符串化,但我似乎无法正确执行。

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

【问题讨论】:

    标签: c macros c-preprocessor stringification


    【解决方案1】:

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

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

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

    【讨论】:

    • 重要的是 stringify 运算符和字符串文字连接是编译时操作,而 char 缓冲区是运行时实体,因此这不可能工作。您不能在编译时连接未知的字符串。
    • 我希望使用单个 fprintf 但我现在明白(从上面的答案和评论)为什么这是不可能的。
    • @Daniel 嗯,可能只用一个 fprintf,但你必须做的事情就是让它成为一个丑陋的解决方案,我不能'不是说我会推荐这个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多