gcc中的位域字节序

Bar*_*rry 5 c c++ gcc endianness bit-fields

位域的字节序由实现定义。有没有一种方法可以在编译时通过某个宏或其他编译器标志检查gcc的位域字节序实际上是什么?

换句话说,给定类似:

struct X {
    uint32_t a : 8;
    uint32_t b : 24;
};
Run Code Online (Sandbox Code Playgroud)

我有什么办法可以在编译时知道a第一个字节还是最后一个字节X吗?

dbu*_*ush 5

在Linux系统中,你可以检查__BYTE_ORDER宏,看它是否是__LITTLE_ENDIAN__BIG_ENDIAN。尽管这不是权威性的,但实际上应该起作用。

struct iphdr在netinet / ip.h 中的定义中暗示了这是正确的方法,该定义用于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. */
  };
Run Code Online (Sandbox Code Playgroud)

  • 它可能是权威的。请参阅 GCC 邮件列表中的此 [评论](https://gcc.gnu.org/ml/gcc/2004-09/msg00581.html):`位字段始终分配给第一个可用位,可能受以下限制其他因素,例如对齐。这意味着它们从 little-endian 的低位开始,而 big-endian 从高位开始。这是做事的“正确”方式。编译器以不同的方式执行此操作是非常不寻常的。` (2认同)