C 预处理器中的 # 和 ## 运算符

17

C99标准文档在与##预处理运算符相关的章节中有以下示例:

In the following fragment:

#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";

The expansion produces, at various stages:

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

In other words, expanding hash_hash produces a new token, consisting of two adjacent sharp signs, but this new token is not the ## operator.

我不理解为什么替换hash_hash会产生##而不是"##"或"#""#"。双哈希之前和之后的单哈希扮演了什么角色?
非常感谢任何回复。

3
单个#符号只是字符,而##(标记)将使它们成为两个#符号,不会被转换为标记。在应用mkstr后,它们将被转换为字符串"##"。 - osgx
1个回答

21

# ## # 中的 ## 在这个表达式中充当转义序列的作用。它将最左边和最右边的 # 进行连接,最终生成标记 ##。如果仅将宏定义为##,则会导致错误,因为连接运算符需要两个操作数。


1
它是如何决定 # ## # 表示 ## 而不是 "##" 接着一个语法错误(因为剩余的 # 没有右操作数)的? - ## 的优先级高于 # 吗? - not-a-user
发生这种情况后,为什么不会导致未定义的行为?因为“##”不是有效的预处理标记。 - Eray Xx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接