【问题标题】:How to concat macros in C如何在 C 中连接宏
【发布时间】:2016-11-01 22:02:52
【问题描述】:

我有一个宏,它将来自__DATE__ 的月份显示为数值字符串文字:

#define MONTH (\
  __DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? "01" : "06") \
: __DATE__[2] == 'b' ? "02" \
: __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? "03" : "04") \
: __DATE__[2] == 'y' ? "05" \
: __DATE__[2] == 'l' ? "07" \
: __DATE__[2] == 'g' ? "08" \
: __DATE__[2] == 'p' ? "09" \
: __DATE__[2] == 't' ? "10" \
: __DATE__[2] == 'v' ? "11" \
: "12")

这工作正常并产生我正在寻找的月份。 printf("%s", MONTH);。但是,我正在尝试将其添加到更大的宏组中并且遇到了问题:

#define MYMONTH "M" MONTH

现在应该生成字符串:M11。但相反,它会产生以下编译器错误:

error: called object is not a function or function pointer
#define MYMONTH   "M" MONTH

我知道你可以通过附加字符串文字和宏来组合它们:

#define COMMA ","
#define EXCLA "!"
#define MYSTR "Hello" COMMA " world" EXCLA

但是当涉及到逻辑时,为什么它不起作用呢?

【问题讨论】:

  • 预处理器只能连接字符串literals。该逻辑的评估不是在预处理时完成,而是稍后——可能在编译时完成,因为它是一个常量表达式。例如,如果 __DATE__ 扩展为 "Oct 31 2016",则 MONTH 扩展为表达式 ("Oct 31 2016"[2] == 'n' ? …),而不是文字。

标签: c string macros c-preprocessor string-concatenation


【解决方案1】:

宏只是在预处理中完成的字符串副本。

如果我们将您的 MONTH 宏复制到 MYMONTH 中,我们会得到:

#define MYMONTH "M" (\
  __DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? "01" : "06") \
: __DATE__[2] == 'b' ? "02" \
: __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? "03" : "04") \
: __DATE__[2] == 'y' ? "05" \
: __DATE__[2] == 'l' ? "07" \
: __DATE__[2] == 'g' ? "08" \
: __DATE__[2] == 'p' ? "09" \
: __DATE__[2] == 't' ? "10" \
: __DATE__[2] == 'v' ? "11" \
: "12")

编译器看起来你正在尝试哪个"M"(<some string here>)

【讨论】:

  • 我不确定我是否遵循。那有什么问题?正如我在问题中说明的那样,您可以将字符串文字与宏连接在一起。 MONTH 将评估为字符串文字(现在为“11”)。那么#define MYMONTH "M" MONTH 有什么问题呢?
  • MONTH 被评估为("11"),因此您的MYMONTH 评估为"M"("11")
  • @linsek:您可以连接字符串 literals。您不能连接 表达式
猜你喜欢
  • 1970-01-01
  • 2015-02-03
  • 2017-08-18
  • 1970-01-01
  • 2018-07-07
  • 2019-11-06
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多