【问题标题】:C preprocessor # and ## operatorsC 预处理器 # 和 ## 运算符
【发布时间】:2011-07-06 10:41:47
【问题描述】:

C99 standard document 在与## 预处理运算符相关的部分中有以下示例:

在以下片段中:

#define hash_hash # ## #
#define mkstr(a) # a
#define in_between(a) mkstr(a)
#define join(c, d) in_between(c hash_hash d)

char p[] = join(x, y); // equivalent to
                       // char p[] = "x ## y";

扩展产生,在各种 阶段:

join(x, y)
in_between(x hash_hash y)
in_between(x ## y)
mkstr(x ## y)
"x ## y"

也就是说,扩展 hash_hash 产生一个新的令牌,包括 两个相邻的尖锐标志,但这个新的 token 不是 ## 运算符。

我不明白为什么 hash_hash 的替换会产生 ## 而不是“##”或“#”“#”。双散列前后单散列的作用是什么?

非常感谢任何回复。

【问题讨论】:

  • ## 前后的单个哈希只是字符,而##(令牌)会将它们变成两个字符##(而不是令牌)。在对它们应用 mkstr 后,它们将被转换为 "##" 的字符串

标签: c concatenation c-preprocessor


【解决方案1】:

# ## # 中的 ## 在此表达式中的作用类似于转义序列。它连接最左边和最右边的#,最终生成令牌##。简单地将宏定义为 ## 会导致错误,因为连接运算符需要两个操作数。

【讨论】:

  • 它如何确定# ## # 表示## 而不是"##" 后跟语法错误(因为剩余的# 没有正确的操作数)? - ## 是否优先于 #
  • 发生这种情况后,为什么它不会导致未定义的行为?由于“##”不是有效的预处理令牌。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-14
  • 2014-12-04
  • 2023-03-17
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多