挂在关于位域的geeksforgeeks上,找到了这个例子:
#include <stdio.h>
struct test {
unsigned int x;
long int y : 33;
unsigned int z;
};
int main() {
struct test t;
unsigned int *ptr1 = &t.x;
unsigned int *ptr2 = &t.z;
printf("%d", ptr2 - ptr1);
return 0;
}
结果,产量是4.但为什么呢? x占用4个字节,y - 8和z - 4.地址x和z的差值必须是8?
答案 0 :(得分:4)
此代码没有可确定的行为。如果没有特定的编译器,就不可能预测它的任何结果。
它包含以下实现定义的行为(标准附件J中的引用):
- 是否将''plain''int位字段视为signed int 位字段或无符号int位字段(6.7.2,6.7.2.1)。
- 除_Bool,signed int和unsigned之外的允许位字段类型 int(6.7.2.1)。
- 位域是否可以跨越存储单元边界(6.7.2.1)。
- 单元内位域分配的顺序(6.7.2.1)。
- 结构的非位域成员的对齐(6.7.2.1)。这个 应该没有问题,除非一个人写的二进制数据 实施由另一个人阅读。
第二个注释也暗示编译器必须具有非标准扩展名。
除此之外,代码还取决于字节顺序,您无法知道位字段中哪些位是MSB和LSB。