Eric Z
Eric Z

Reputation: 14535

Endianess inside a byte

Recently I'm tracking down a bug that appears when the two sides of the network communication have different endianness. One side has already sent a telegram marking lastSegment while the other side is still waiting for the last segment endlessly.

I read this code:

#ifndef kBigEndian
    struct tTelegram
    {
       u8 lastSegment : 1;
       u8 reserved: 7;
       u8 data[1];
    };
#else
    struct tTelegram
    {
       u8 reserved: 7;
       u8 lastSegment : 1;
       u8 data[1];
    };
#endif

I know endianness is concerned for multi-byte type, e.g., int, long, etc. But why it cares in the previous code? lastSegment and reserved are inside a single byte.

Is that a bug?

Upvotes: 2

Views: 137

Answers (2)

Jerry Coffin
Jerry Coffin

Reputation: 490713

When it comes to bitfields, ordering is not guaranteed even between different compilers running on the same CPU. You could theoretically even get a change of order just by changing flags with the same compiler (though, in fairness, I have to add that I've never actually seen that happen).

Upvotes: 1

Doug T.
Doug T.

Reputation: 65649

You have 16 bits in your struct. On a 32-bit or 64-bit architecture, depending on the endianess, data may come "before" reserved and lastSegment or it may come "after" when looking at the raw binary. IE If we consider 32 bits, your struct may be packed along 32-bit boundaries. It might look like this:

 padbyte1 padbyte2 data lastSegment+reserved

or it may look like this

 lastSegment+reserved data padbyte1 padbyte2

So when you put those 16 bits over the wire then reinterpret them on the other side, do you know if you're getting data or lastSegment?

Your problem isn't within the byte, its where data lies in relation to reserved and lastSegment.

Upvotes: 2

Related Questions