gcc中的位域字节序

时间:2017-12-01 19:53:56

标签: c++ c gcc endianness bit-fields

位域的字节顺序是实现定义的。有没有办法在编译时检查是否通过一些宏或其他编译器标志,gcc的bitfield字节顺序实际上是什么?

换句话说,给出了类似的东西:

struct X {
    uint32_t a : 8;
    uint32_t b : 24;
};

有没有办法让我在编译时知道aX中的第一个还是最后一个字节?

2 个答案:

答案 0 :(得分:4)

在Linux系统上,您可以查看__BYTE_ORDER宏,看看它是__LITTLE_ENDIAN还是__BIG_ENDIAN。虽然这不具有权威性,但在实践中它应该有效。

提示这是正确的方法是在netinet / ip.h中定义struct iphdr,这是针对IP头的。第一个字节包含两个4位字段,这些字段实现为位域,因此顺序非常重要:

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. */
  };

答案 1 :(得分:0)

当位域为8位的倍数时,似乎体系结构的字节序无关紧要。

请参见here [godbolt.org]

在此示例中,我选择了arm体系结构,因为它支持大小端字节,并且比较差异也很容易。

请注意,无论体系结构是大字节序还是小字节序,在两种情况下,8位字段都在结构的开头。

我在godbolt上测试了所有可以为is_8bit_tag_at_start函数生成可读汇编代码的编译器,它们似乎都返回true。