如何防止 C 预处理器宏扩展为重复值?
How to keep c preprocessor macro from expanding into repeated values?
我正在使用 X 宏生成 MCU 引脚配置 table。 table 看起来像这样。
#define IO_DEFS\
/* Port Pin Type Name */\
IODEF(00, 0, input, "Pin A")\
IODEF(00, 1, input, "Pin B")\
IODEF(01, 2, output, "Pin C")\
IODEF(01, 4, output, "Pin D")\
IODEF(02, 0, input, "Pin E")\
IODEF(03, 7, input, "Pin F")\
IODEF(03, 8, output, "Pin G")\
IODEF(03, 9, input, "Pin H")\
但是,在我需要由此 table 生成的各种扩展中,我需要一个 enum,如下所示:
typedef enum PORT_IO_Defs_Tag
{
PORT_00,
PORT_01,
PORT_02,
PORT_03,
} PORT_IO_Defs_T;
但问题是在使用下一个代码创建宏扩展时:
#undef IODEF
#define IODEF(port, pin, type, name) PORT_##port,
typedef enum PORT_IO_Defs_Tag
{
IO_DEFS
} PORT_IO_Defs_T;
我得到的是以下内容:
typedef enum PORT_IO_Defs_Tag
{
PORT_00,
PORT_00,
PORT_01,
PORT_01,
PORT_02,
PORT_03,
PORT_03,
PORT_03,
} PORT_IO_Defs_T;
我知道这个宏扩展是正确的,但不是我想要的,因为这会为枚举和编译错误生成多个相同的值。
我的问题是,是否有人知道我可以用来实现此目的的一些 C 预处理器技巧或技巧。我正在阅读这篇文章 https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms,其中包含一些非常有趣的预处理器宏技术,但我无法调整它们以获得我需要的结果。
如果可能的话,我需要在不使用 M4 宏处理器的情况下实现这一点。
此致。
您可以为 IODEF
宏添加一个附加参数,指示首次出现的端口
#define IO_DEFS\
/* Port Pin Type Name */\
IODEF(00, 0, input, "Pin A", 1)\
IODEF(00, 1, input, "Pin B", 0)\
IODEF(01, 2, output, "Pin C", 1)\
IODEF(01, 4, output, "Pin D", 0)\
IODEF(02, 0, input, "Pin E", 1)\
IODEF(03, 7, input, "Pin F", 1)\
IODEF(03, 8, output, "Pin G", 0)\
IODEF(03, 9, input, "Pin H", 0)\
并像这样更改您的宏
#undef IODEF
#define PRINT_0(port)
#define PRINT_1(port) PORT_##port,
#define IODEF(port, pin, type, name, flag) PRINT_##flag(port)
现在,每个端口只会在您的 enum
中出现一次
typedef enum PORT_IO_Defs_Tag
{
PORT_00, PORT_01, PORT_02, PORT_03,
} PORT_IO_Defs_T;
我正在使用 X 宏生成 MCU 引脚配置 table。 table 看起来像这样。
#define IO_DEFS\
/* Port Pin Type Name */\
IODEF(00, 0, input, "Pin A")\
IODEF(00, 1, input, "Pin B")\
IODEF(01, 2, output, "Pin C")\
IODEF(01, 4, output, "Pin D")\
IODEF(02, 0, input, "Pin E")\
IODEF(03, 7, input, "Pin F")\
IODEF(03, 8, output, "Pin G")\
IODEF(03, 9, input, "Pin H")\
但是,在我需要由此 table 生成的各种扩展中,我需要一个 enum,如下所示:
typedef enum PORT_IO_Defs_Tag
{
PORT_00,
PORT_01,
PORT_02,
PORT_03,
} PORT_IO_Defs_T;
但问题是在使用下一个代码创建宏扩展时:
#undef IODEF
#define IODEF(port, pin, type, name) PORT_##port,
typedef enum PORT_IO_Defs_Tag
{
IO_DEFS
} PORT_IO_Defs_T;
我得到的是以下内容:
typedef enum PORT_IO_Defs_Tag
{
PORT_00,
PORT_00,
PORT_01,
PORT_01,
PORT_02,
PORT_03,
PORT_03,
PORT_03,
} PORT_IO_Defs_T;
我知道这个宏扩展是正确的,但不是我想要的,因为这会为枚举和编译错误生成多个相同的值。
我的问题是,是否有人知道我可以用来实现此目的的一些 C 预处理器技巧或技巧。我正在阅读这篇文章 https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms,其中包含一些非常有趣的预处理器宏技术,但我无法调整它们以获得我需要的结果。
如果可能的话,我需要在不使用 M4 宏处理器的情况下实现这一点。
此致。
您可以为 IODEF
宏添加一个附加参数,指示首次出现的端口
#define IO_DEFS\
/* Port Pin Type Name */\
IODEF(00, 0, input, "Pin A", 1)\
IODEF(00, 1, input, "Pin B", 0)\
IODEF(01, 2, output, "Pin C", 1)\
IODEF(01, 4, output, "Pin D", 0)\
IODEF(02, 0, input, "Pin E", 1)\
IODEF(03, 7, input, "Pin F", 1)\
IODEF(03, 8, output, "Pin G", 0)\
IODEF(03, 9, input, "Pin H", 0)\
并像这样更改您的宏
#undef IODEF
#define PRINT_0(port)
#define PRINT_1(port) PORT_##port,
#define IODEF(port, pin, type, name, flag) PRINT_##flag(port)
现在,每个端口只会在您的 enum
中出现一次typedef enum PORT_IO_Defs_Tag
{
PORT_00, PORT_01, PORT_02, PORT_03,
} PORT_IO_Defs_T;