字节顺序和大小为 1 的位域

Endianness and bitfields of size 1

我认为字节顺序不应该影响最多 1 个字节的结构。但这是我的小端机器上的代码:

#include <iostream>
#include <bitset>
#include <cstdint>
#include <cstring>

using namespace std;

static_assert(sizeof(uint8_t) == 1, "Wrong uint8_t size");

struct Pieces {
    uint8_t flag : 1;
    uint8_t value : 7;
};

static_assert(sizeof(Pieces) == 1, "Something went wrong with Pieces size");

int main()
{
    uint8_t value = 0b10001111;
    Pieces pieces;
    std::memcpy(&pieces, &value, 1);

    cout << bitset<8>(value) << endl;
    // 10001111
    cout << bitset<1>(pieces.flag) << bitset<7>(pieces.value) << endl;
    // 11000111
    return 0;
}

结果不正确。但是,如果我更改 pieces 结构中 flagvalue 成员的顺序,那么结果是正确的。但它不应该像我写的那样吗?我希望 value 中的第一个(从左边数起)位是标志。看起来像字节顺序问题,但字节顺序不应该定义字节顺序,而不是位?

有人可以向我解释一下这里到底发生了什么吗?

所以让我从评论中收集所有信息。

标准中似乎没有指定位字段的顺序,因此取决于实现。标准的相关部分是(感谢@molbdnilo):

§9.6: "Bit-fields are assigned right-to-left on some machines, left-to-right on others."

另请注意其他评论。似乎位字段的顺序在内存中只是颠倒了。这似乎也与普通字段的顺序一致,并且可能与字节顺序一致(如果有人可以在大端机器上检查它,我将不胜感激)。

我想这就是 "right-to-left on some machines" 和 "left-to-right on others" 的意思。然而,这是我的解释,如前所述,我们不应该依赖它。