我有一个typedeffed结构和一个联合。 union包含结构和单个uint32_t
。目标是为foo
分配一个与结构中“位”对应的值。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef struct {
uint32_t valA :1;
uint32_t valB :1;
uint32_t valC :1;
uint32_t valD :1;
uint32_t valE :1;
} ValStruct_Type;
typedef union {
ValStruct_Type valStruct;
uint32_t valUint;
} ValUnion_Type;
uint32_t foo = 0;
int main(void)
{
ValStruct_Type Vals;
Vals.valA = 0x0;
Vals.valB = 0x1;
Vals.valC = 0x0;
Vals.valD = 0x1;
Vals.valE = 0x1;
ValStruct_Type *Vals_ptr;
Vals_ptr = &Vals;
foo = ((ValUnion_Type *)Vals_ptr)->valUint;
return 0;
}
foo变成:
Decimal: 4194330
Hex: 0x40001a
Binary: 10000000000000000011010
谁可以准确地解释这里发生的事情(指向结构指针的联合指针,与联盟成员相关?)?
其次:除了第1,3和4位之外,为什么foo
的第22位设置?
答案 0 :(得分:2)
由于未定义的行为,设置了位22。您已经创建了一个从未完全初始化的局部变量,然后设置了5位。剩下的比特是他们碰巧发生的事情,未初始化的本地人就是这种情况。
关于你问题的第一部分......有什么不清楚的?你的问题(union pointer to a struct pointer, defererenced to a union member
)似乎已经回答了。将某些内容转换为它已经存在的类型没有任何效果。
答案 1 :(得分:1)
定义联合时,指示编译器为任何适合其任一成员的实例保留足够的内存。
当你输入一个位域时,它被填充到某个字节大小(通常为4或8个字节,但在你的小例子中可能是1个字节)。
由于你只为你的struct分配了足够的内存(用sizeof(ValStruct_Type)
检查),然后将它转换为一个占用更多内存的联合,你就会得到未定义的行为。
无论填充的那部分是什么,都会被复制到foo
。
你所做的大致等于
char a = 0x1a;
int foo = *(int *)&a;
要获得正确的行为