codewarrior
codewarrior

Reputation: 991

how does endianness affect bitfield defintion in struct?

Use iphdr as first example:

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

My question 1, as far as i know, endianness only affects when dealing with multi-bytes, in other words if there is only 1 byte, there is no "bit order" such a thing. In above definition, ihl+version= 8 bits = 1 byte, ihl and version reside in a byte, why should we care endianness and reverse order of ihl and version?

if "bit order" is an issue, my question 2 is why another struct ip_options doesn't care about endianness?

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];
};

Upvotes: 1

Views: 324

Answers (2)

chux
chux

Reputation: 154362

C does not require byte endian-ness to dictate if __u8 ihl:4 uses the 4 MSBits or 4 LSBits.

why should we care endianness and reverse order of ihl and version?

Original author may want to overlay struct iphdr on a hardware address, play with union magic or achieve a certain serial communication order.

The approach is not highly portable, but may have met the original limited needs.

if "bit order" is an issue, my question 2 is why another struct ip_options doesn't care about endianness?

It is an inconstancy.

It may not be relevant to cope with endian-ness past the header. The header type struct iphdr may need a endian-agnostic coding, yet once those members are assigned, remaining code interprets accordingly. This could be the case if all but the header has the #if defined(__LITTLE_ENDIAN_BITFIELD).

.tiff did something like this.

Upvotes: 2

Andrew Henle
Andrew Henle

Reputation: 1

The C standard leaves bitfield implementation all but completely unspecified, so there's no way to tell.

Per 6.7.2.1 Structure and union specifiers, paragraph 11:

An implementation may allocate any addressable storage unit large enough to hold a bit-field. 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.

There's effectively no portable way to use bitfields in C. The only thing specified is the "if enough space remains" part. But even the size of whatever that space may be is completely up in the air, as "[a]n implementation may allocate any addressable storage unit large enough to hold a bit-field."

Upvotes: 1

Related Questions