C语言中位域内存的使用

C语言中位域内存的使用,c,struct,field,bit,C,Struct,Field,Bit,为什么它返回96而不是64? 若我对位域的位求和,我将得到64 编辑: var变量具有0xFFFFFF而不是0xFFFFFF->var变量具有0x3FFFFFFF00FFFFFF而不是0xffffffffffffff* #include <stdio.h> #include <stdlib.h> #include <stdint.h> typedef struct{ uint32_t a : 24; uint32_t b : 20;

为什么它返回96而不是64? 若我对位域的位求和,我将得到64

编辑:

var
变量具有
0xFFFFFF
而不是
0xFFFFFF
->
var
变量具有
0x3FFFFFFF00FFFFFF
而不是
0xffffffffffffff
*

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct{
    uint32_t a : 24;
    uint32_t b : 20;
    uint32_t c : 10;
    uint32_t d : 6;
    uint32_t e : 4;
}MyType_t;

int main(){
    MyType_t test;
    test.a = -1;
    test.b = -1;
    test.c = -1;
    test.d = -1;
    test.e = -1;

    uint64_t var = *((uint64_t*)&test);

    printf("MyType_t: %d bit\n", sizeof(MyType_t) * 8);//96 bit
    printf("Var: %#llX\n", var);//0x3FFFFFFF00FFFFFF
    return 0;
}

字段a和b不可能包含在单一类型的uint32\t中:

typedef struct{
    uint32_t a : 24;    //first 32 bits
    uint32_t b : 20;    //second 32 bits
    uint32_t c : 10;    //
    uint32_t d : 6;     //third 32 bits
    uint32_t e : 4;     //
}MyType_t;
因此,结构的大小是uint32\t大小的三倍



代码的行为
uint64\u t var=*((uint64\u t*)和测试)未定义。

字段a和b不可能包含在单一类型的uint32\t中:

typedef struct{
    uint32_t a : 24;    //first 32 bits
    uint32_t b : 20;    //second 32 bits
    uint32_t c : 10;    //
    uint32_t d : 6;     //third 32 bits
    uint32_t e : 4;     //
}MyType_t;
因此,结构的大小是uint32\t大小的三倍



代码的行为
uint64\u t var=*((uint64\u t*)和测试)未定义。

很好地说明了为什么不应该依赖于位字段的重新解释…如果不参考特定的实现,
a
b
是否可以放入单个
uint32\u t
,则没有多大关系,因为该标准在位字段的声明类型和存储它的可寻址存储单元的大小之间没有任何关联。事实上,该标准对位字段在专用于存放位的可寻址存储单元中的布局没有多少要求。@JohnBollinger是的,我正在对OPs的实现进行假设。标准的这一部分非常松散。如果不参考特定的实现,
a
b
是否可以放入单个
uint32\u t
中,很好地说明了为什么不应该依赖于对位字段的重新解释,因为该标准在位字段的声明类型和存储它的可寻址存储单元的大小之间没有任何关联。事实上,该标准对位字段在专用于存放位的可寻址存储单元中的布局没有多少要求。@JohnBollinger是的,我正在对OPs的实现进行假设。标准的这一部分非常松散。将
uint32\u t
更改为
uint64\u t
,然后
sizeof(MyType\u t)
将给出
8
而不是
12
@风向标,你这样说的依据是什么?也就是说,我不怀疑您所说的对于某些实现是正确的,但是我非常确定标准中没有任何东西要求它是正确的。特别是,即使实现选择使用类型为
uint32\u t
的单元来保存位(这不是必需的),是否在这些存储单元之间拆分位字段还是由实现定义的。@JohnBollinger只是因为它看起来很明显,总共有64位,并且字段大小在32位之间发生了中断。虽然我可以看到一些实现可能会成功地使用发布的代码,但我看不到如何使用64位类型可能不会成功。@WeatherVane,因为声明的位字段类型与其位所在的存储单元大小没有必要的关联。仅将
uint32\u t
位字段声明更改为
uint64\u t
不需要在布局或结果大小上有任何差异(例如,仍然可以使用三个32位单元)@JohnBollinger-hmmm是的:声明的类型必须至少与要编码的位字段一样大。将
uint32\u t
更改为
uint64\u t
,然后
sizeof(MyType\u t)
将给出
8
,而不是
12
@风向标,您这样说的依据是什么?也就是说,我不怀疑您所说的对于某些实现是正确的,但是我非常确定标准中没有任何东西要求它是正确的。特别是,即使实现选择使用类型为
uint32\u t
的单元来保存位(这不是必需的),是否在这些存储单元之间拆分位字段还是由实现定义的。@JohnBollinger只是因为它看起来很明显,总共有64位,并且字段大小在32位之间发生了中断。虽然我可以看到一些实现可能会成功地使用发布的代码,但我看不到如何使用64位类型可能不会成功。@WeatherVane,因为声明的位字段类型与其位所在的存储单元大小没有必要的关联。仅将
uint32\u t
位字段声明更改为
uint64\u t
不需要在布局或结果大小上有任何差异(例如,仍然可以使用三个32位单元)。@JohnBollinger-hmmm是的:声明的类型必须至少与要编码的位字段一样大。