响水凹

欢迎来到 Guang-Wen Duan (Dennis Duan) 的个人 Wiki

用户工具

站点工具


computer:c:tips:struct_layout

结构体成员的地址分布

C编译器对结构体(struct)对象的成员按地址增序的方式进行空间分配,即第一个成员的地址就是整个结构体对象的起始地址,其他成员按定义顺序依次排在后面。

例如:

struct {
        int a, b, c;
} s;
int *p = &s.a;
int *q = &s.b;

则p<q成立。

同样的,结构体的位段(bit field)成员也遵循类似的递增规则,即先定义的位段成员从bit 0开始分配。但与普通结构体成员不同的是,位段的分布受字节序的影响:高端字节序的机器,是left-to-right的方式,最高位(leftmost)数据放在bit 0的位置,而小端字节序是right-to-left的方式,恰好相反。所以,在定义结构体的位段成员时,两种字节序的书写顺序是相反的。

例如下面ipv4的头部定义中,版本号(version)与报头长度(internet header length,ihl)位于第一个字节,各占4bit,不同字节序的定义顺序刚好相反:

struct iphdr
  {
#if __BYTE_ORDER == __LITTLE_ENDIAN
    unsigned int ihl:4;
    unsigned int version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    unsigned int version:4;
    unsigned int ihl:4;
#else
# error "Please fix <bits/endian.h>"
#endif
    u_int8_t tos;
    u_int16_t tot_len;
    u_int16_t id;
    u_int16_t frag_off;
    u_int8_t ttl;
    u_int8_t protocol;
    u_int16_t check;
    u_int32_t saddr;
    u_int32_t daddr;
    /*The options start here. */
  };
computer/c/tips/struct_layout.txt · 最后更改: 2014/11/01 02:02 由 127.0.0.1