关于这个话题已经存在疑问(特别是How to get address of some struct member in array of structures)。
我的问题如下:
当我们使用struct
描述硬件设备时,每个结构成员将对应于硬件设备的一些寄存器 - 我们如何确保结构的每个成员在硬件的每个寄存器上正确映射? / p>
编译器的ABI指示成员的对齐,用户也会犯一些错误 - 确保映射正确完成的唯一方法是在运行时进行检查。 地图文件(至少对于GNU ld)没有提供关于结构成员放置的任何线索。
是否有办法知道每个结构成员所在的编译器或链接时间?
答案 0 :(得分:2)
您可以在C ++中使用offsetof
static_assert
。
例如,完全随意的
#include <cstddef>
struct iom { // off,len
uint32_t rx; // +0,4
uint32_t tx; // +4,4
uint64_t clk; // +8,8
uint16_t irq; // +16,2
};
static_assert(offsetof(iom,rx)==0);
static_assert(offsetof(iom,tx)==4);
static_assert(offsetof(iom,clk)==8);
static_assert(offsetof(iom,irq)==16);
如果static_assert
失败,例如因为编译器将成员与64位边界对齐,则需要使用编译器特定的方法来更改对齐和填充。例如,使用gcc,
} __attribute__((packed));
在结构定义的末尾。
NB。我已回答C ++ 17。
C ++ 11或14,或C11需要一条错误消息作为static_assert
的第二个参数,尽管你可以将整个事物包装在一个宏中,为你编写一个很好的字符串。
offsetof
宏也适用于C.