Reputation: 991
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
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
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