任何人都可以在下面的例子中解释C预处理器的行为吗?

我正在实现一个C宏预处理器(C99)……

我对以下行为感到惊讶….

EX1:

 #define PASTE(x)X _ ## x
 #define EXPAND(x)PASTE(x)
 #define TABSIZE 1024
 #define BUFSIZE TABSIZE

 PASTE(BUFSIZE)
 EXPAND(BUFSIZE)

扩展为:

 X_BUFFSIZE
 X_1024

EX2:

 #define EXPAND(s)TO_STRING(s)
 #define TO_STRING(s)#s
 #define四个4

 TO_STRING(四)
 EXPAND(四)

扩展到:

 “四个一”
 “4”

我已经完成了C的“免费”标准,但我找不到以下内容……

  1. 实际上预处理器执行了多少次传递?
  2. 它首先替换一个宏,然后替换其他宏等等
  3. 或者它是否存储并替换为#define s逐个遇到?
  4. 文件包含是先完成还是宏扩展?

您应该阅读本页面的初学者。 它包含gem,例如:

C标准规定,在用可能扩展的参数替换任何参数之后,将扫描替换列表以查找嵌套宏。 此外,替换列表中在此扫描期间未展开的任何标识符在将来都不再符合扩展条件,如果它们未被扩展的原因是所讨论的宏被禁用。

我认为可以从中推断出没有固定的传递次数:每次发生宏扩展(生成“替换列表”)时,扫描新创建的文本以进行进一步的扩展。 这是一个递归过程。

实际上预处理器执行了多少次传递?

  1. 它通过该# PARAMETER的字符串化替换#PARAMETER的所有出现
  2. 它加入了所有具有## inbetween的标记
  3. 它用它们的值替换参数的所有剩余次数
  4. 它递归地扩展替换文本以发现其他宏。 (宏本身在这些递归调用中被阻止。)

它是先取代一个宏然后取代其他等等,还是将它们存储并替换为#defines逐个遇到?

它按照程序文本中遇到的顺序替换宏,或者如上所述在递归替换期间替换宏。

文件包含是先完成还是宏扩展?

首先,如果#include的参数不包含在<>""则会扩展#include的参数。 那么必须导致<>""某些内容