我不知道为什么,但位字段分配没有按预期工作.可能只是一个愚蠢的事情,但我无法找到问题所在.
任何帮助都非常受欢迎.
typedef struct a {
unsigned char a1 :1;
unsigned char a2 :3;
unsigned char a3 :2;
unsigned char a4 :2;
} __attribute__((packed)) mystruct;
int main() {
mystruct d;
d.a1 = 0;
d.a2 = 2;
d.a3 = 1;
d.a4 = 2;
unsigned char *val = (unsigned char*) &d;
printf("%02X \n", *val);
printf("%02X \n", sizeof(hola));
exit(0);
}
Run Code Online (Sandbox Code Playgroud)
返回输出:
94
01
Run Code Online (Sandbox Code Playgroud)
预期产量:
26
01
Run Code Online (Sandbox Code Playgroud)
关于位字段的几乎所有内容都是实现定义的.特别是单位中的位顺序.
(C99,6.7.2.1p10)"单位内的位域分配顺序(从高位到低位或低位到高位)是实现定义的."
在您的实现中,这些位首先存储在单元lsb(最低有效位)中,而不是像您期望的那样存储在msb(最高有效位)中.
你有的是:
[a1.0] [a2.0] [a2.1] [a2.2] [a2.0] [a3.1] [a4.0] [a4.1]
0 0 1 0 1 0 0 1
bit 0 - bit 7
lsb - msb
Run Code Online (Sandbox Code Playgroud)
这是0x94如果你考虑的最左比特是最显著位.
ASCII艺术:
MSB LSB
+----+----+----+----+----+----+----+----+
|a4.1|a4.0|a3.1|a3.0|a2.2|a2.1|a2.0| a1 |
+----+----+----+----+----+----+----+----+
| 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 |
+----+----+----+----+----+----+----+----+
| 0x9 | 0x4 |
+----+----+----+----+----+----+----+----+
Run Code Online (Sandbox Code Playgroud)
如上所述,行为是实现定义的; 这是组织数据的两种合法方式之一,似乎是您机器上选择的格式.替代行为是.
MSB LSB
+----+----+----+----+----+----+----+----+
| a1 |a2.2|a2.1|a2.0|a3.1|a3.0|a4.1|a4.0|
+----+----+----+----+----+----+----+----+
| 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 |
+----+----+----+----+----+----+----+----+
| 0x2 | 0x6 |
+----+----+----+----+----+----+----+----+
Run Code Online (Sandbox Code Playgroud)
这显然是你期望的行为.
由于它是实现定义的,因此您可以查看手册并查找编译器的功能,因为编译器必须记录其行为.
如果您需要担心可移植性,则需要考虑如何组织结构定义,以便按照您在所使用的每个平台上工作的方式工作.