字节序如何影响struct中的位域定义?

时间:2019-12-04 00:49:52

标签: c endianness

使用IPHDR作为第一个示例:

struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
    __u8    ihl:4,
            version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
    __u8    version:4,
            ihl:4;
#else
#error  "Please fix <asm/byteorder.h>"
#endif

    /* other fields are emitted. */
};

我的问题1,据我所知,字节序仅在处理多字节时才受影响,换句话说,如果只有1个字节,则没有“位顺序”这样的事情。在上面的定义中,ihl + version = 8位= 1个字节,ihl和version驻留在一个字节中,为什么我们要关心ihl和version的字节顺序和倒序?

如果“位顺序”是一个问题,我的问题2是为什么另一个struct ip_options不关心字节顺序?

struct ip_options {
    __be32      faddr;
    __be32      nexthop;
    unsigned char   optlen;
    unsigned char   srr;
    unsigned char   rr;
    unsigned char   ts;
    unsigned char   is_strictroute:1,  // why this byte doesn't care endianness?
                    srr_is_hit:1,
                    is_changed:1,
                    rr_needaddr:1,
                    ts_needtime:1,
                    ts_needaddr:1;
    unsigned char   router_alert;
    unsigned char   cipso;
    unsigned char   __pad2;
    unsigned char   __data[0];
};

2 个答案:

答案 0 :(得分:2)

C不需要字节字节序来指示__u8 ihl:4使用4个MSBit还是4个LSBit。

  

我们为什么要关心ihl和版本的字节序和倒序?

原始作者可能希望将struct iphdr覆盖在硬件地址上,玩union魔术或达成某种串行通信顺序。

该方法不是高度可移植的,但是可能已经满足了最初的有限需求。

  

如果“位顺序”是一个问题,我的问题2是为什么另一个struct ip_options不关心字节顺序?

这很不稳定。

处理标头后的字节序可能无关紧要。标头类型struct iphdr可能需要与字节序无关的编码,但是一旦分配了这些成员,其余的代码就会相应地解释。如果除标题之外的所有标题都具有#if defined(__LITTLE_ENDIAN_BITFIELD),可能会是这种情况。

.tiff做了这样的事情。

答案 1 :(得分:1)

C标准几乎完全没有说明位域的实现,因此无法说明。

6.7.2.1 Structure and union specifiers, paragraph 11

  

实现可以分配任何足够大的可寻址存储单元来容纳位字段。如果有足够的空间,则应将紧随结构中另一个位域之后的位域打包到同一单元的相邻位中。如果剩余空间不足,则将实现不适当的位字段放入下一个单元还是与相邻单元重叠。 单位内位域的分配顺序(从高位到低位或从低位到高位)是实现定义的。未指定可寻址存储单元的对齐方式。

在C语言中,实际上没有可移植的方式使用位域。唯一指定的是“如果还有足够的空间”部分。但是,无论该空间可能有多大,都无法确定,因为“ [实现]可能会分配足够大的可寻址存储单元来容纳位域。”

相关问题