【问题标题】:How to modify the argument of a multi-argument macro?如何修改多参数宏的参数?
【发布时间】:2015-09-17 20:26:43
【问题描述】:

我在代码中定义了各种类型的 printf 宏:

#define DEBUG(...) printf(__VA_ARGS__)

这很好用:

DEBUG("Hello %d",1);

将与

相同
printf("Hello %d",1);

现在我可以让我的宏也编辑传入的参数,比如说,在第一个参数的末尾添加一个 \n 吗? IE。这样

DEBUG("Hello %d",1);

变成

printf("Hello %d\n",1);

【问题讨论】:

    标签: c macros variadic-functions


    【解决方案1】:

    我建议使用:

    #define DEBUG(fmt, ...) printf(fmt "\n", __VA_ARGS__)
    

    缺点是您必须至少有一个非格式字符串参数,即您不能将宏用作:

    DEBUG("foo");
    

    了。

    对于某些编译器,有一些变通方法允许空 __VA_ARGS__

    #define DEBUG(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
    

    在 gcc 中(感谢 M. Oehm)。

    【讨论】:

    • 对于空参数列表有依赖编译器的解决方案,例如 gcc 中的##__VA_ARGS__ 语法,但它们当然不可移植。
    • @MOehm: 如果多个printf() 语句没问题,那么也可以拆分为两个来解决fmt 问题:#define DEBUG(...) do { printf(__VA_ARGS__); printf("\n"); } while(0)
    • @TimČas:是的,Jean Jung 的回答已经表明了这一点。
    【解决方案2】:

    如果您希望您的 \n 始终在决赛中,您可以再添加一条 printf 声明:

    #define DEBUG(...) printf(__VA_ARGS__); printf("\n")
    ...
    DEBUG("hello %d", 1);
    DEBUG("hello %d", 1);
    

    输出:

    你好 1

    你好 1

    正如其他人所指出的,在这种情况下这不会按预期工作:

    if (cond) 
        DEBUG("Blah")
    

    所以你必须这样定义宏:

    #define DEBUG(...) do { printf(__VA_ARGS__); printf("\n"); } while(0)
    

    感谢 M. Oehm 和 undur_gongor

    【讨论】:

    • 好主意,但您应该用 the 包装两个单独的调用,以便它们像单个函数一样工作。否则,if (cond) DEBUG("Hey!") 之类的代码将无法按预期工作。
    • 常见的做法是#define DEBUG(...) do { printf(__VA_ARGS__); printf("\n"); } while(0)
    • printf("\n"); 等价于puts("");
    • 无参数问题的另一种解决方法是只使用两个宏(例如,DEBUG 用于参数,DEBUG0 如果只有一个字符串)
    【解决方案3】:

    如果您知道第一个参数始终是字符串文字,则可以使用字符串文字连接来做到这一点。

    如果你有宏

    #define EXAMPLE(A,B) \
    printf("%s", A B)
    

    然后在代码中

    EXAMPLE("foo ", "bar\n");
    

    将与

    相同
    printf("%s", "foo bar\n");
    

    (由于您没有显示完整的代码,我假设您可以根据您的情况进行调整)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-20
      • 2020-08-20
      • 2014-10-01
      • 2019-07-15
      相关资源
      最近更新 更多