为什么 ip_hl 和 ip_v 的顺序按系统字节顺序改变

Why order of ip_hl and ip_v changes by system byteorder

为什么 ip_hl 和 ip_v 的顺序会根据系统字节顺序改变?

当二进制字符串大于 1 个字节时,我必须关心字节顺序。 但是,ip_hl 和 ip_v 是一个字节,所以我想我不需要关心 ip_hl 和 ip_v.

的字节顺序
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN 
    u_char  ip_hl:4,        /* header length */
        ip_v:4;         /* version */
#endif
#if BYTE_ORDER == BIG_ENDIAN 
    u_char  ip_v:4,         /* version */
        ip_hl:4;        /* header length */
#endif
    u_char  ip_tos;         /* type of service */
    short   ip_len;         /* total length */
    u_short ip_id;          /* identification */
    short   ip_off;         /* fragment offset field */
...
};

`

ip_vip_hl 字段是 bit-fields。标准不保证结构中 bit-fields 的顺序。

来自 C standard 的第 6.7.2.1 节:

11 An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

在这个代表 IP header 的特定结构的情况下,它是在系统 header 文件中定义的,因此它具有一些关于位域顺序的实现知识。因为 IP header 必须先有版本字段,然后是 header 长度,所以 #if 检查系统的字节顺序以确定将字段放置在结构中的顺序,以便它们最终出现在正确的位置,允许将结构覆盖到接收到的数据包缓冲区上以读取 IP header。据推测,小端系统会颠倒位域的顺序,而大端系统不会。

然而,这不是您应该尝试在用户代码中执行的操作,因为它在不同系统上的行为可能不同。像这样的代码在系统 header 中是允许的,因为它们驻留在可以安全地做出某些假设的特定实现中。