【发布时间】:2022-01-12 21:08:01
【问题描述】:
我正在尝试获取自定义位字段我尝试了这种方法:
struct foo
{
unsigned z : 10;
unsigned y : 16;
unsigned x : 1;
unsigned w : 16;
};
int main()
{
foo test({0x345, 0x1234, 0x1 ,0x1234});
char bytes[8] = {0};
std::cout << sizeof(test) << std::endl;
memcpy(bytes, &test, 8);
std::cout << sizeof(bool) << std::endl;
for (int i = 0; i < sizeof(bytes) / sizeof(char); i++)
{
std::cout << std::bitset<8>(bytes[sizeof(bytes) / sizeof(char) - i - 1]);
}
std::cout << "" << std::endl;
return 0;
}
通过我正在尝试的测试,它返回了我:
0000000000000000000100100011010000000100010010001101001101000101
(00000000000000000 | 0010 010 0011 0100 | 000001 | 0001 0010 0011 0100 |11 0100 0101应对应:0x1234 |0x1 | 0x1234 | 0x345)
我从右到左阅读它,在右侧我有10 第一位(
11 0100 0101),然后我有下一个 16 位 (0001 0010 0011 0100)。在该字段之后,我预计下一个数据只需要one 位,但我在最后一个16 位(0001 0010 0011 0100)之前有6 位(000001)而不是(1)。
请问您对此有什么见解吗?
【问题讨论】:
-
编译器可以随意排序、填充和对齐位域。在这种情况下,您的编译器似乎决定向
x添加 5 位填充,以便整体结构是 32 位对齐的。 -
我该如何解决?这是非常奇怪的情况,特别是因为我想在我的位中有一个特定的定义,因为我愿意用它来定义一个硬件消息。
-
Little Endian 也可能会扭曲字节的“预期”视图。但是你想解决什么问题?如果您试图保证特定的位顺序(例如网络协议或总线通信),请编写您自己的序列化(位打包)代码。
-
您实际上使用位操作运算符,如
<<、>>、|或&将二进制消息打包到字节数组中,而不是依赖编译器来完成工作给你。 -
unsigned char buffer[16]是 128 位。
标签: c++ c++11 bit-manipulation