串联预处理:
这行:串联预处理:
#define hash_hash # ## #
会产生##
而是基于不是未定义行为:
如果结果不是一个有效的预处理标记,该行为是未定义 。
编辑:
换句话说,扩大hash_hash产生新令牌,由两个相邻的尖锐的迹象, 但这新令牌不是## 操作者 。
预处理标记的类别为:
预处理标记分为五大类:标识符, 预处理数字,字符串文字,标点符号和其他
是##
新的令牌属于其他类别如果没有UB。
请注意:请花些时间阅读与之相关的问题和答案,甚至在下载之前。
这是标准的一个例子。 ##
是有效的预处理令牌。正如那里使用的那样,它是形成连接运算符的令牌。它在C语法中根本没有意义(预处理后)。但它出现在标点符号列表中,如*
或++
。
由于没有语法规则会匹配它,所以不可避免的结果是将被诊断的语法错误。 除非,它被传递给另一个宏,它将其字符串化或忽略它。
#define IGNORE(X)
#define STRINGIZE_LIT(X) #X
#define STRINGIZE(X) STRINGIZE_LIT(X)
IGNORE(hash_hash) // OK, token is not passed to semantic analysis.
printf(STRINGIZE(hash_hash)); // OK, same as printf("##");
你没有回答我的问题,我知道它是在那里使用的串联。 – Sabrina
@Sabrina你已经编辑了这个问题,但答案保持不变。是的,令牌处于“其他”类别。 – Potatoswatter
您认为未定义的行为意味着什么?这意味着它可以做任何事情。 –