使用结构体时常为了对齐或匹配需要定义一些保留字段,比如定义一个结构体来描述某设备寄存器,因为寄存器本身不是连续的所以在空缺位置要定义保留字段,如下所示:
typedef struct {
volatile UINT16 fifo;
volatile UINT16 ucsr;
volatile UINT16 recerved0;
volatile UINT16 mcr;
volatile UINT16 recerved1;
volatile UINT16 baud;
volatile UINT16 fsr;
} FPGA_UART_REGS;
尤其是在有多个保留字段时,命名又不能重复,写起来会略麻烦。
这里利用宏定义实现了一种用法简单的保留字段定义宏 RESERVED(size)
。
#define RESERVED_1(type, name, line, size) type name##line[size]
#define RESERVED_0(line, size) RESERVED_1(char, recerved, line, size)
#define RESERVED(size) RESERVED_0(__LINE__, size)
利用 RESERVED(size)
重新定义上面的结构体:
typedef struct {
volatile UINT16 fifo;
volatile UINT16 ucsr;
volatile RESERVED(2);
volatile UINT16 mcr;
volatile RESERVED(2);
volatile UINT16 baud;
volatile UINT16 fsr;
} FPGA_UART_REGS;
RESERVED(2)
的展开过程如下:
volatile RESERVED(2);
--> volatile RESERVED_0(__LINE__, size);
--> volatile RESERVED_1(char, recerved, __LINE__, 2);
--> volatile char recervedxxx[2]; //xxx为宏__LINE__对应的行号
比如结构体的起始行号为100,则展开后的结构体为:
100: typedef struct {
101: volatile UINT16 fifo;
102: volatile UINT16 ucsr;
103: volatile char recerved103[2];
104: volatile UINT16 mcr;
105: volatile char recerved105[2];
106: volatile UINT16 baud;
107: volatile UINT16 fsr;
108: } FPGA_UART_REGS;
这样使用同一个宏 RESERVED(size)
配合需要保留的字节数就可以任意定义保留字段而不需要考虑命名问题了。