我具有以下构造,意在获取包含四个12位值的48位值并提取它们。
struct foo {
union {
unsigned __int64 data;
struct {
unsigned int a : 12;
unsigned int b : 12;
unsigned int c : 12;
unsigned int d : 12;
unsigned int unused : 16;
};
};
} foo;
有问题的数据然后使用
进行分配foo.data = (unsigned __int64)Value;
值此处最初是用于存储数据的双精度值。
我对位字段的假设是
- 数据保存变量应足够大以容纳整个 数据和未签名。因此, unsigned __int64 可容纳48位。
- 每个位域成员的类型应足以容纳 分配给它且未签名的位数。
- 如果所有位域成员都保持相同类型,则是一个好主意 可能。 (以避免对齐问题?)
- 实际上不需要未使用成员。
这些对吗?
测试
Value = 206225551364
我们得到一个值,其中应包含位
0000 0011 0000 0000 0100 0000 0000 0011 0000 0000 0100
这应该导致
a: 0000 0000 0100 = 4
b: 0000 0000 0011 = 3
c: 0000 0000 0100 = 4
d: 0000 0000 0011 = 3
但是运行此返回的实际值是
a: 4
b: 3
c: 48
d: 0
尽管这些值应在 unsigned int的范围内,但有时会更改所使用的类型。因此,感觉就像与将数据添加到位字段后如何解释数据有关。
通过添加 #pragma pack(1),据我所知,它与对齐方式有关,但是使用频率不是很高,我突然得到了预期的值。
struct foo {
union {
unsigned __int64 data;
#pragma pack(1)
struct {
unsigned int a : 12;
unsigned int b : 12;
unsigned int c : 12;
unsigned int d : 12;
unsigned int unused : 16;
};
};
} foo;
a: 4
b: 3
c: 4
d: 3
但是我不愿意接受这一点。我想了解它,从而确保它确实有效,并且看起来不仅仅在值不超过4位的情况下起作用。
所以
- 为什么我看到这个问题开始?
- #pragma pack 语句可以解决什么问题?
- 有人能推断出什么时候会成问题吗?是因为 值是12位而不是8位或16位吗?