这一行:
#define hash_hash # ## #
将生成##
但不是基于以下内容的未定义行为:
如果结果不是有效的预处理令牌,则行为是 未定义。
修改
换句话说,扩展hash_hash会产生一个新令牌 两个相邻的尖锐标志,,但这个新标记不是## 操作
预处理令牌的类别是:
预处理令牌分为五大类:标识符, 预处理数字,字符串文字,标点符号和其他
##
新令牌是否属于其他类别如果没有UB 。
注意:请花时间阅读问题和答案,甚至在弃用之前。
答案 0 :(得分: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( "##" );