两遍 C 预处理?

Two pass C preprocessing?

有没有办法让 C 预处理器 (GCC) 运行 两次通过,以完全展开宏?

我正在尝试使用引脚的抽象名称在微控制器上定义支持端口 I/O 的宏:

#define LED_RED E, (1<<6)

#define SetPin(port, mask)    PORT ## port ## SET = (mask)
#define ClearPin(port, mask)  PORT ## port ## CLR = (mask)
#define ReadPin(port, mask)   (PORT ## port) & (mask)

然后在我的代码中:

SetPin(LED_RED);
ClearPin(LED_RED);
result = ReadPin(LED_RED);

这意味着扩展到:

PORTESET = (1<<6);
PORTECLR = (1<<6);
result = (PORTE) & (1<<6);

这无法编译 - 我得到:

error: macro "SetPin" requires 2 arguments, but only 1 given.

虽然这确实可以编译并且工作正常:

SetPin(E, (1<<6));

那么...如何让 C 编译器完全展开这些宏?

或者,如果不是那样,如何使这种事情起作用?

您必须通过附加宏传递参数。

#define LED_RED E, (1<<6)
#define SetPin2(port, mask)    PORT ## port ## SET = (mask)
#define SetPin(x) SetPin2(x)

SetPin(LED_RED);

这是因为宏替换的顺序:

  1. 首先,确定类函数宏的参数。这已经 如果参数数量错误(如您的代码中所示),则会失败。
  2. 然后,参数标记被放入替换列表。除非它们在 ### 旁边,否则它们会被宏扩展 之前。
  3. 最后,扫描生成的替换列表以进行进一步的宏替换。

有了额外的宏 "in between",第 2 步就有机会替换 LED_RED