字节内的恩迪亚

Endianess inside a byte

本文关键字:字节      更新时间:2023-10-16

最近我正在追踪一个错误,当网络通信的两端具有不同的字节序时会出现该错误。一方已经发了一封电报,标记lastSegment而另一方仍在无休止地等待最后一段。

我读了这段代码:

#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

我知道字节序与多字节类型有关,例如 int、long 等。但是为什么它在前面的代码中关心呢? lastSegmentreserved位于单个字节内。

这是一个错误吗?

你的结构中有 16 位。在 32 位或 64 位体系结构上,根据字节data可能出现在reservedlastSegment之前,或者在查看原始二进制文件时可能"之后"。IE 如果我们考虑 32 位,您的结构可能会沿 32 位边界打包。它可能看起来像这样:

 padbyte1 padbyte2 data lastSegment+reserved

或者它可能看起来像这样

 lastSegment+reserved data padbyte1 padbyte2

因此,当您将这 16 位放在电线上然后在另一侧重新解释它们时,您知道您是data还是lastSegment吗?

您的问题不在字节内,而是datareservedlastSegment相关的位置。

当涉及到位字段时,即使在在同一 CPU 上运行的不同编译器之间也不能保证排序。理论上,您甚至可以通过使用相同的编译器更改标志来更改顺序(尽管,公平地说,我必须补充一点,我从未真正看到过这种情况发生)。