【发布时间】:2016-09-22 19:42:13
【问题描述】:
在处理一些框架结构时,我遇到了一个奇怪的行为。 我很快在独立的示例代码中对其进行了测试,具体如下:
struct non_alligned_struct
{
uint8_t flag;
// start of uint32 bit fields
uint32_t a:2;
uint32_t b:2;
uint32_t c:1;
uint32_t d:1;
uint32_t e:1;
uint32_t f:1;
uint32_t g:3;
uint32_t h:1;
uint32_t i:1;
uint32_t j:3;
uint32_t k:3;
uint32_t l:1;
uint32_t m:1;
uint32_t n:1;
uint32_t o:1;
uint32_t p:3;
uint32_t q:2;
uint32_t r:1;
uint32_t s:1;
uint32_t t:2;
//4 bytes ends here
// shouldn't this start at 5th byte ??
uint16_t u;
uint16_t v:13;
uint16_t w:3;
uint16_t x;
uint16_t y:13;
uint16_t z:3;
};
int main()
{
struct non_alligned_struct obj1;
void *ptr1 = &obj1;
void *ptr2 = &(obj1.u);
printf("ptr1: %p, ptr2: %p, ptr2 - ptr1: %d\n", ptr1, ptr2, ptr2 - ptr1);
return 0;
}
输出: ptr1: 0x7fff3216a620, ptr2: 0x7fff3216a626, ptr2 - ptr1: 6
问题:为什么 ptr2 - ptr1 应该是 6。根据我的计算,它应该是 5。结构也是 13 个字节,所以它对齐了 4 个字节,并且填充是以奇怪的方式完成的。我通过为成员变量提供随机值来验证,我观察到填充是在以下 bold locations
完成的00000000: 01 22 31 10 67 00 fe ff 86 01 fe ff 86 01 00 00
【问题讨论】:
-
ptr2-ptr1 绝对等于 6...
-
在 MSVC 中,如果我将
struct与#pragma pack(push, 1)和#pragma pack(pop)括起来,它会给出您预期的结果5,否则会给出8。我不得不将void*指针更改为char*,因为void*类型上的指针算法是实现定义的。 -
对
void*s 进行算术的约束违反。您的编译器有义务为此错误发出诊断信息。
标签: c struct memory-alignment bit-fields packing