chq*_*lie 5 c concatenation language-lawyer c-preprocessor
似乎可以定义一个宏来连接 3 个标记为:
#define concat3(a,b,c) a##b##c
Run Code Online (Sandbox Code Playgroud)
中间令牌(例如由生成的令牌a##b
或b##c
必须是有效的预处理器令牌)是否可以concat3(.,.,.)
成功粘贴到所有符合要求的实现上?(1)
(1) 许多编译器支持..
作为 case 范围的标记,这使其成为有效标记,但是 C 标准没有定义这个标记,那么concat3()
宏会在不支持它的架构上失败吗?
在我看来,每个中间令牌都必须有效,否则就被认为是未定义的行为。我下面引用的部分来自C11标准,但C99和C20草案中的语言似乎是相同的。
第 6.10.3.3 节涵盖了运算符的实际解释##
,并特别指的是连接前面和后面的标记,即它们是成对处理的。第 3 段有点令人困惑,因为它单独提到了地标替换(即,类似函数的宏的扩展,其中参数没有预处理标记),然后指定“如果结果不是有效的预处理标记,则行为是不明确的”。目前尚不清楚它是指地标案例还是所有串联。
然而,J.2 节将“预处理运算符的结果##
不是有效的预处理标记”标识为无条件的未定义行为,所以我认为这可能有助于澄清我上面的观点。
另请注意,该标准规定运算符的求值顺序##
未指定,因此每种可能的串联组合都必须有效。