简体   繁体   English

gcc中的位域字节序

[英]Bitfield endianness in gcc

The endianness of bitfields is implementation defined. 位域的字节顺序是实现定义的。 Is there a way to check, at compile time, whether via some macro or other compiler flag, what gcc's bitfield endianness actually is? 有没有办法在编译时检查是否通过一些宏或其他编译器标志,gcc的bitfield字节顺序实际上是什么?

In other words, given something like: 换句话说,给出类似的东西:

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

Is there a way for me to know at compile time whether or not a is the first or last byte in X ? 有没有办法让我在编译时知道 aX的第一个还是最后一个字节?

On Linux systems, you can check the __BYTE_ORDER macro to see if it is __LITTLE_ENDIAN or __BIG_ENDIAN . 在Linux系统上,您可以检查__BYTE_ORDER宏以查看它是__LITTLE_ENDIAN还是__BIG_ENDIAN While this is not authoritative, in practice it should work. 虽然这不具有权威性,但在实践中它应该有效。

A hint that this is the right way to do it is in the definition of struct iphdr in netinet/ip.h, which is for an IP header. 提示这是正确的方法是在netinet / ip.h中定义struct iphdr iphdr,它是针对IP头的。 The first byte contains two 4-bit fields which are implemented as bitfields, so the order is important: 第一个字节包含两个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. */
  };

It might be of some interest that when the bitfields are multiples of 8-bits across, it appears that endianness of the arcitecture does not matter. 当位域是8位的倍数时,可能有一些兴趣,似乎arcitecture的字节序无关紧要。

See here [godbolt.org] 这里 [godbolt.org]

I chose the arm architecture in this godbolt example because that supports both big and little endian, and it is easy to compare the differences. 我在这个godbolt示例中选择了arm架构,因为它支持大端和小端,并且很容易比较差异。

Note that whether the architecture is big or small endian, in both cases the 8-bit field is at the start of the struct. 请注意,无论架构是大端还是小端,在这两种情况下,8位字段都位于结构的开头。

I tested all of the compilers on godbolt that could generate readable assembly code for the is_8bit_tag_at_start function, and they all appeared to return true. 我测试了godbolt上的所有编译器,它们可以为is_8bit_tag_at_start函数生成可读的汇编代码,并且它们似乎都返回true。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM