在位域的情况下,哪一个更好用,unsigned char或unsigned int,为什么?

我只想知道下面的结构声明。 哪一个更好用于内存分配,为什么? 那么在无符号字符和无符号整数的情况下填充呢?

struct data{ unsigned char a:3; unsigned char b:4; }; 

 struct data{ unsigned int a:3; unsigned int b:4; }; 

Solutions Collecting From Web of "在位域的情况下,哪一个更好用,unsigned char或unsigned int,为什么?"

应使用带signed intunsigned int类型声明位域。 其他类型可能也可能不支持。

来自Atmel

in the C Standard, only “unsigned (int)” and “int” are acceptable datatypes for a bitfield member. Some compilers allow “unsigned char” .......

在c99标准(§6.7.2.1#4)

位字段的类型应该是_Boolsigned intunsigned int或其他实现定义的类型的合格或非限定版本。

如果使用的实际类型说明符是int或定义为inttypedef-name ,则无论bit-field是有signed还是unsigned ,都是实现定义的。

(§6.7.2.1#15)

在结构或联合的末尾可能有未命名的填充。

一个实现可以分配任何足够大的可寻址存储单元来容纳一个位域。

另外(§6.7.2.1#11)

没有声明符的位域声明,只有冒号和宽度,表示未命名的位域。 作为一个特殊情况,宽度为0的位结构成员表示没有进一步的位字段将被放入先前的位字段(如果有的话)被放置的单元中。

未命名的位域结构成员对于填充符合外部施加的布局是有用的。

正如Amogh(坚定地)和PHIfounder指出的那样,唯一完全可移植的类型是_Boolsigned intunsigned int 。 然而,许多编译器允许其他的整型类型来填充位域。 实际中的位字段通常用于表示设备寄存器,其中通常每一位或一组位具有其自己的含义。 这些位的包装由C标准的6.7.2.1和11所规定

一个实现可以分配足够大的可寻址存储单元来容纳一个位域。 如果剩余足够的空间,紧接在结构中的另一个比特字段之后的比特字段应被打包到相同单元的相邻比特中。 如果剩余空间不足,则将不合适的比特字段放入下一个单元,或与相邻单元重叠是实现定义的。 一个单元内的位域分配顺序(从高到低或从低到高)是实现定义的。 未指定可寻址存储单元的对齐方式。

许多编译器都采用了“可寻址存储单元”是源代码中指定类型的约定。 例如gcc编译器不允许类型为unsigned char的9位位字段,但它允许它为一个unsigned int类型。 在你的例子中,Pentium的gcc编译器使用unsigned char的结构体大小为1个字节,而使用unsigned int为4个字节。 许多编译器也采用了这样的惯例,即如果一个比特位不合适,它将不会与下一个单位重叠。 然而,这可以使用如标准的6.7.2.1和12所规定的0宽度位域来强制实施

没有声明符的位域声明,只有冒号和宽度,表示未命名的位域。 作为一种特殊情况,宽度为0的位域结构成员表示没有其他位域被放入先前位域(如果有的话)所在的单元中。

如果混合位字段和非位字段,则6.7.2.1和15中规定,位字段和非位字段的可寻址单元将具有不同的地址

在一个结构对象中,非位域成员和位域所在的单元的地址增加了它们的声明顺序。 指向结构对象的指针(适当地转换)指向其初始成员(或者如果该成员是位域,则指向其驻留的单元),反之亦然。 结构对象中可能有未命名的填充,但不在其开头。

一些体系结构的应用程序二进制接口(ABI)强制执行定义的选择,以确保该体系结构的不同编译器的互操作性。