C标准给出了以下示例:
#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";
但它也说'#和##运算符的评估顺序是未指定的。'
为什么hash_hash
的扩展保证被解释为应用于#的##运算符,而不是应用于##的#运算符?
答案 0 :(得分:3)
因为'#'仅作为运算符出现在类似函数的宏中并且后跟参数名称...但是hash_hash不是类似函数的宏而且没有跟随'#'按参数名称。
答案 1 :(得分:0)
引用C99:
标点符号是具有独立句法和语义的符号 意义。 根据上下文,它可以指定要执行的操作 执行(反过来可能产生一个值或一个功能指示符, 在这种情况下产生副作用或其某种组合 被称为运算符(其他形式的运算符也存在于某些运算符中) 上下文)。操作数是操作员操作的实体。
#
和##
是标点符号。
此外:
6.10.3.1参数替换
在识别出类似函数宏的调用参数之后,参数 替代发生。替换列表中的参数,除非 之前是#或##预处理令牌或后跟## 预处理令牌(见下文),由相应的替换 其中包含的所有宏都已扩展后的参数。之前 被替换后,每个参数的预处理标记都是完全的 宏被替换,好像它们形成了预处理文件的其余部分; 没有其他预处理令牌可供使用。