C预处理器中的参数检查

Parameter checking in C preprocessor

如何在编译时测试C中宏参数的字符串值?

我正在 C (GNU) 中为微控制器编写包装器宏。

我有一些宏是这样工作的:

#define _ReadBits(port, mask)      (PORT ## port) & (mask)
#define ReadBits(portmask)         _ReadBits(portmask) 
#define SWITCH D, (1<<7)

这样我可以说:

foo = ReadBits(SWITCH);

我会得到

foo = PORTD & (1<<7);

效果很好。我想扩展这些来做这样的事情:

#define _ConfigAnalog(port, mask)  BUILD_BUG_ON(port != B); AD1PCFGCLR = (mask)
#define ConfigAnalog(portmask)    _ConfigAnalog(portmask)

也就是说,如果参数port不是B,我希望发生编译时错误(因为这个微控制器只能配置 端口 B 作为模拟)。

C 中有什么方法可以做到这一点吗?

How can I test the string value of a macro parameter in C at compile?

你不能。

根据 C99 6.10.1 条件包含,预处理器条件必须是一个整数常量表达式,并且可以测试是否定义了宏(使用 #if#ifdef identifier#if defined(identifier))。

我自己想出来了:

#define PORT_B_SUPPORTS_ANALOG

#define __CheckPort(p)  PORT_##p##_SUPPORTS_ANALOG
#define __ConfigAnalogBits(mask) AD1PCFGCLR = (mask)

#define _ConfigAnalogBits(port, mask)  __CheckPort(port); __ConfigAnalogBits(mask)
#define ConfigAnalogBits(portmask)     _ConfigAnalogBits(portmask)

#define NO_GOOD C, (1<<3)
#define VOLTAGE B, (1<<3)

void tryit(void)
{
    ConfigAnalogBits(VOLTAGE);
    //ConfigAnalogBits(NO_GOOD);
}

如果 "port" 是 B,则 _CheckPort 编译为空语句。

如果 "port" 是其他任何内容,则会发生构建错误。