两次通过C预处理?

时间:2015-07-13 20:45:14

标签: c gcc macros c-preprocessor

有没有办法让 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);

这不会编译 - 我得到:

  

错误:宏&#34; SetPin&#34;需要2个参数,但只有1个参数。

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

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

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

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

1 个答案:

答案 0 :(得分:13)

您必须通过其他宏传递参数。

#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. 最后,扫描生成的替换列表以进行进一步的宏替换。
  4. 使用额外的宏&#34;在&#34;之间,第二步有机会替换LED_RED