问题
I thought that endianness is not supposed to affect structs of size at most 1 byte. But here's the code on my little endian machine:
#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;
}
The result is incorrect. But if I change the order of flag
and value
members in pieces
struct then the result is correct. But isn't it supposed to be as I've written? I'm expecting the first (counting from the left) bit in value
to be the flag. It looks like endianess issue but isn't endianess supposed define the order of bytes, not bits?
Could someone explain to me what's exactly going on here?
回答1:
So let me gather all the info from comments.
It seems that the order of bit fields is not specified in the standard and thus is implementation dependent. The relevant part of the standard is (thanks to @molbdnilo):
§9.6: "Bit-fields are assigned right-to-left on some machines, left-to-right on others."
Also let me note other comments. It seems that the order of bit fields is simply reversed in memory. This seems to be consistent with the order of normal fields as well and is probably consistent with endianness (I would appreciate if someone can check it on a big-endian machine).
I guess that's what "right-to-left on some machines" and "left-to-right on others" means. However this is my interpretation and as stated earlier we should not depend on it.
来源:https://stackoverflow.com/questions/43333327/endianness-and-bitfields-of-size-1