地图文件中的成员结构地址?

时间:2017-11-09 13:09:21

标签: c++ c linker hardware ld

关于这个话题已经存在疑问(特别是How to get address of some struct member in array of structures)。

我的问题如下: 当我们使用struct描述硬件设备时,每个结构成员将对应于硬件设备的一些寄存器 - 我们如何确保结构的每个成员在硬件的每个寄存器上正确映射? / p>

编译器的ABI指示成员的对齐,用户也会犯一些错误 - 确保映射正确完成的唯一方法是在运行时进行检查。 地图文件(至少对于GNU ld)没有提供关于结构成员放置的任何线索。

是否有办法知道每个结构成员所在的编译器或链接时间?

1 个答案:

答案 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.