为什么序列迭代在C macro中工作?

时间:2017-05-16 06:35:37

标签: c++ c macros

编写C宏时,有一个叫做“序列迭代”的技巧。它看起来如下:

#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
#define FUNCTION(name) void name();
#define FUNCTION_TABLE(seq) CAT(FUNCTION_TABLE_1 seq, _END)
#define FUNCTION_TABLE_1(x) FUNCTION(x) FUNCTION_TABLE_2
#define FUNCTION_TABLE_2(x) FUNCTION(x) FUNCTION_TABLE_1
#define FUNCTION_TABLE_1_END
#define FUNCTION_TABLE_2_END

FUNCTION_TABLE((x) (y) (z) (e))

序列,即FUCTION_TABLE的参数,将逐一处理。但是,据我所知,令牌不会在同一范围内扩展两次。因为它是“涂成蓝色”。展开FUNCTION_TABLE_2时,宏FUNCTION_TABLE_1已经绘制好了。它为什么还在扩展?

2 个答案:

答案 0 :(得分:2)

类似函数的宏替换是一个递归过程:

  • 除了###
  • 之外,宏首先以非递归方式展开
  • 然后,递归地,任何不是###的操作数的令牌被扩展
  • ###(如果有)应用于生成的操作数
  • 转到1,直到步骤1-3没有变化。

(这比描述更复杂!)。所以对于你的代码:

  • FUNCTION_TABLE((x) (y) (z) (e))扩展为CAT(FUNCTION_TABLE_1 (x) (y) (z) (e), _END)
  • CAT(X, _END)扩展为PRIMITIVE_CAT(expand(X), _END)。立即制定expand(X)
    • FUNCTION_TABLE_1 (x) (y) (z) (e)扩展为FUNCTION(x) FUNCTION_TABLE_2 (y) (z) (e)
      • FUNCTION(x)扩展为void x();
      • FUNCTION_TABLE_2 (y) (z) (e)扩展为FUNCTION(y) FUNCTION_TABLE_1 (z) (e)
      • FUNCTION(y)扩展为void y();
      • FUNCTION_TABLE_1 (z) (e)扩展为FUNCTION(z) FUNCTION_TABLE_2(e)
        • FUNCTION(z)扩展为void z();
        • FUNCTION_TABLE_2(e)扩展为FUNCTION(e) FUNCTION_TABLE_1
        • FUNCTION(e)扩展为void e();
        • 结果: void e(); FUNCTION_TABLE_1
        • 结果: void z(); void e(); FUNCTION_TABLE_1
      • 结果: void y(); void z(); void e(); FUNCTION_TABLE_1
      • 结果: void x(); void y(); void z(); void e(); FUNCTION_TABLE_1
  • 因此,在完全展开X后,让我们回顾一下我们所处的位置:PRIMITIVE_CAT(void x(); void y(); void z(); void e(); FUNCTION_TABLE_1, _END)
  • 这会扩展为void x(); void y(); void z(); void e(); FUNCTION_TABLE_1_END
  • 重新扫描后,会显示void x(); void y(); void z(); void e();

答案 1 :(得分:1)

这个想法是在宏扩展中,参数的所有扩展都将以相同的BLUE-SET开始。

driver.findElement(By.id("divImgAnnualAllowanceType")).getAttribute("value"); 内,FUNCTION_TABLE(seq)内所有参数的扩展将始终以BLUE-SET = {seq}开始。因此,在输入FUNCTION_TABLE_1后,BLUE-SET被添加到FUNCTION_TABLE_1 seq,但是当这完成后,它将回到x的范围,再次使用FUNCTION_TABLE开始扩展。

因此,第一次展开BLUE-SET={seq}并在FUNCTION_TABLE_1(x)展开此展开,但当BLUE-SET={seq,x}的展开完成时,它会回到FUNCTION_TABLE_1,它会然后再展开此范围FUNCTION_TABLE和INSIDE FUNCTION_TABLE_2(y) BLUE-SET = {seq,x}等等。