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

时间:2017-04-10 21:41:46

标签: c++ endianness

我认为字节序不应该影响大小最多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;
}

结果不正确。但是,如果我更改flag结构中valuepieces成员的顺序,则结果是正确的。但它不应该像我写的一样吗?我期待value中的第一个(从左数起)位是标志。它看起来像endianess问题,但不是endianess假定定义字节的顺序,而不是位?

有人可以向我解释这里究竟发生了什么吗?

1 个答案:

答案 0 :(得分:0)

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

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

  

§9.6:“在某些机器上从右到左分配位字段,在其他机器上从左到右分配。”

另请注意其他评论。似乎位域的顺序在内存中简单地颠倒过来。这似乎与正常字段的顺序一致,并且可能与字节顺序一致(如果有人可以在大端机器上检查它,我将不胜感激。)

我猜这就是“在某些机器上从右到左”和“在其他机器上从左到右”的含义。然而,这是我的解释,如前所述,我们不应该依赖它。