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

如何防止c预处理器宏扩展为重复值?,c,macros,c-preprocessor,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,

我正在使用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预处理器技巧或技术,我可以用来实现这一点。我正在阅读这篇文章,其中包含一些非常有趣的预处理器宏技术,但我无法调整它们以获得我需要的结果

如果可能,我需要在不使用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)
现在,每个端口只会在您的枚举中出现一次

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

按照上面的例子,定义是否总是成对的,每对都有相同的端口号?如果是这样的话,我可以看到一个可能的,但有点笨拙的解决方案。@PaulR不,定义并不总是成对的。这可能有很多种可能的组合。定义的端口数不同,每个端口的管脚定义数也不同。但绝对没有指定此表的可能定义方式。这里唯一一致的是,从00到NN,始终会按端口号订购。@PaulR:不;如果这个例子可信的话,有一个
02
和三个
03
端口。或者根本不可能有01和8个03。这只是一个示例,组合与任何模式都没有关系。@Barmar-这是对X宏的一个很好的解释。