2017-02-04 84 views
2

这行:串联预处理:

#define hash_hash # ## # 

会产生##而是基于不是未定义行为:

如果结果不是一个有效的预处理标记,该行为是未定义 。

编辑:

换句话说,扩大hash_hash产生新令牌,由两个相邻的尖锐的迹象, 但这新令牌不是## 操作者

预处理标记的类别为:

预处理标记分​​为五大类:标识符, 预处理数字,字符串文字,标点符号和其他

##新的令牌属于其他类别如果没有UB

请注意:请花些时间阅读与之相关的问题和答案,甚至在下载之前。

+4

您认为未定义的行为意味着什么?这意味着它可以做任何事情。 –

回答

7

这是标准的一个例子。 ##有效的预处理令牌。正如那里使用的那样,它是形成连接运算符的令牌。它在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("##"); 
+2

你没有回答我的问题,我知道它是在那里使用的串联。 – Sabrina

+1

@Sabrina你已经编辑了这个问题,但答案保持不变。是的,令牌处于“其他”类别。 – Potatoswatter