【问题标题】:What am I doing wrong with this variadic macro in C?我在 C 中对这个可变参数宏做错了什么?
【发布时间】:2021-11-19 04:34:35
【问题描述】:

我正在做一个大学项目,我制作了一个 printf 的宏包装器,它可以为文本着色、打印文件、函数和指令行,并带有基于 errno 的字符串错误。

#define PRINT_WITH_COLOR(color, title, message, errno_code) printf(color "[" title "] " message " %s::%s:%d [%s]\n" RESET_COLOR_CONSOLE, __VA_ARGS__, __FILE__, __func__, __LINE__, strerror(errno_code));

这最初被分成多个 printf 但由于多线程,我面临的问题是,当我没有参数传递逗号时,逗号仍然存在并且程序无法编译。 出于这个原因,我使用 ## 来删除可变参数周围的逗号:

#define PRINT_WITH_COLOR(color, title, message, errno_code) printf(color "[" title "] " message " %s::%s:%d [%s]\n" RESET_COLOR_CONSOLE, ## __VA_ARGS__, __FILE__, __func__, __LINE__, strerror(errno_code));

我认为它可以正常工作,因为我的 VS 代码没有收到任何错误,但是 gcc 编译器给了我这个错误,指向 __VA_ARGS__ , 旁边的正确逗号

expected expression before ‘,’ token

编辑 这是一个示例用法: 我通过调用这个宏来间接使用它

#define PRINT_WARNING(err_code, message, ...) PRINT_WITH_COLOR(YELLOW_COLOR, "Warning", message, __VA_ARGS__)

在我的代码中我就是这样使用它的

PRINT_WARNING(EINVAL, "File %s cannot be written!", pathname);

控制台中的输出是黄色消息 [警告] 无法写入文件 foo!文件路径::func:line [errno msg]

【问题讨论】:

  • @chux-ReinstateMonica 谢谢你告诉我,我已经更新了我的帖子!似乎每个宏调用都会出现编译错误

标签: c gcc variadic-macros


【解决方案1】:

实际上是PRINT_WARNING的宏扩展最终导致了问题,你也应该在那里使用##。我想你也想通过err_code

#define PRINT_WARNING(err_code, message, ...) \
        PRINT_WITH_COLOR(YELLOW_COLOR, "Warning", message, err_code, ##__VA_ARGS__)

PRINT_WITH_COLOR 宏也应该以, ...) 结尾

#define PRINT_WITH_COLOR(color, title, message, errno_code, ...) \
        printf(color "[" title "] " message " %s::%s:%d [%s]\n" RESET_COLOR_CONSOLE, \
               ##__VA_ARGS__, __FILE__, __func__, __LINE__, strerror(errno_code));

【讨论】:

  • PRINT_WARNING 中的## 也解决了这个问题!!我虽然参数将由最后一个宏自动处理,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多