如何防止c预处理器宏扩展为重复值?

时间:2015-10-12 15:22:51

标签: c macros c-preprocessor

我使用X宏生成MCU引脚配置表。表格看起来像这样。

#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")\

但是,在我需要从这个表中生成的各种扩展中,我需要一个 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宏处理器的情况下实现此目的。

问候。

1 个答案:

答案 0 :(得分:2)

您可以为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)

现在,每个端口只会出现一次枚举

typedef enum PORT_IO_Defs_Tag
{
    PORT_00, PORT_01, PORT_02, PORT_03,
} PORT_IO_Defs_T;