#和##扩展顺序

时间:2013-01-18 09:31:59

标签: c macros c-preprocessor

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的扩展保证被解释为应用于#的##运算符,而不是应用于##的#运算符?

2 个答案:

答案 0 :(得分:3)

因为'#'仅作为运算符出现在类似函数的宏中并且后跟参数名称...但是hash_hash不是类似函数的宏而且没有跟随'#'按参数名称。

答案 1 :(得分:0)

引用C99:

  

标点符号是具有独立句法和语义的符号   意义。 根据上下文,它可以指定要执行的操作   执行(反过来可能产生一个值或一个功能指示符,   在这种情况下产生副作用或其某种组合   被称为运算符(其他形式的运算符也存在于某些运算符中)   上下文)。操作数是操作员操作的实体。

###是标点符号。

此外:

  

6.10.3.1参数替换

     

在识别出类似函数宏的调用参数之后,参数   替代发生。替换列表中的参数,除非   之前是#或##预处理令牌或后跟##   预处理令牌(见下文),由相应的替换   其中包含的所有宏都已扩展后的参数。之前   被替换后,每个参数的预处理标记都是完全的   宏被替换,好像它们形成了预处理文件的其余部分;   没有其他预处理令牌可供使用。