【发布时间】:2012-02-09 21:04:56
【问题描述】:
我想知道是否可以在 C 中强制位域对齐。使用下面代码中的变量我知道写入 _align_bytes 然后从 bits 读取是未定义的(反之亦然),因为它取决于实现。下面的代码是“说服” bits 连续存储在 unsigned short 大小的东西中的有效方法吗?我相信(减去任何字节序问题)这段代码是正确的......但位域和联合是我最不熟悉的两个 C 主题。
我正在做一个低级微控制器项目,并且想要一种无需大量位掩码即可读取配置位的简单方法。感谢您提供任何提示和建议。
山姆
附:请忽略我对字节顺序所做的任何假设,因为我正在进行的这个项目非常低级,不打算移植到其他设备/平台。
#include <stdio.h>
#include <assert.h>
typedef union packet {
struct {
unsigned int bit0 : 1;
unsigned int bit1 : 1;
unsigned int bit2 : 1;
unsigned int bit3 : 1;
unsigned int bit4 : 1;
unsigned int bit5 : 1;
unsigned int bit6 : 1;
unsigned int bit7 : 1;
unsigned int bit8 : 1;
unsigned int bit9 : 1;
unsigned int bit10 : 1;
unsigned int bit11 : 1;
unsigned int bit12 : 1;
unsigned int bit13 : 1;
unsigned int bit14 : 1;
unsigned int bit15 : 1;
} bits;
unsigned short _align_bytes;
} packet_t;
int main(int argc, char *argv[]) {
assert(sizeof(unsigned short) == 2);
unsigned short data = 0xA05F;
packet_t *p = (packet_t *)&data;
printf("%u", p->bits.bit15);
printf("%u", p->bits.bit14);
printf("%u", p->bits.bit13);
printf("%u", p->bits.bit12);
printf("%u", p->bits.bit11);
printf("%u", p->bits.bit10);
printf("%u", p->bits.bit9);
printf("%u", p->bits.bit8);
printf("%u", p->bits.bit7);
printf("%u", p->bits.bit6);
printf("%u", p->bits.bit5);
printf("%u", p->bits.bit4);
printf("%u", p->bits.bit3);
printf("%u", p->bits.bit2);
printf("%u", p->bits.bit1);
printf("%u", p->bits.bit0);
return 0;
}
【问题讨论】:
-
您应该对
bits和_align_bits使用相同的类型。如果您的 int 大小不同(例如 sizeof(int) == 4 和 sizeof(short) == 2)并且位域按您不期望的顺序排序,那么您的bits可能不会重叠_align_bits。字节序和位域排序是不同的。 -
“实现依赖”不是“未定义”。而且由于您使用的是微控制器编译器,这种黑客行为很常见,我认为您很安全。因为,是的,这是强制位域对齐/填充的正常方式。
标签: c struct bit-fields memory-alignment unions