C++ 位域的问题
Issues with C++ bitfields
我必须用特定的数据格式写一个文件header。为简单起见,我们假设它是:
- 位[0-7]:索引a
- 位[8-9]:索引b
- 位[10-15]:索引c
它们都是简单的无符号整数。我想我可能会使用位字段来获得一个很好的语法。我定义了
struct Foo {
unsigned int a : 8, b : 2, c : 6;
};
然而,我得到 sizeof(Foo) == 4
。为什么?我希望这里有一个 2 字节的结构。编译器是否在我的字段之间添加了填充?如果我使用 unsigned char
作为我的成员类型,我得到 2 个字节的大小。
在 cppreference 上,它说:
Multiple adjacent bit fields are usually packed together (although
this behavior is implementation-defined).
这是否意味着我不能依赖于将字段打包在一起?最后,我将使用 memcpy
将此 struct
转换为字节流并将其写入文件。这不是很好地使用位字段吗?这只有在保证这些位被打包在一起时才有效。
编辑:实际的 header 与 GIF format 相关。许多索引都被打包成几个字节。其中一些由1、2、3或更多位组成。
来自 [class.bit]/1 [摘录]:
[...] Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined.
并且,来自 [defns.impl.defined]:
implementation-defined behavior
behavior, for a well-formed program construct and correct data, that
depends on the implementation and that each implementation documents
因此,对于可移植的实现,您不能依赖任何特定类型的行为来实现 implementation-defined 行为。但是,如果您正在为特定平台和编译器开发,您 可以 在一定程度上依赖记录的 implementation-defined 行为。
我必须用特定的数据格式写一个文件header。为简单起见,我们假设它是:
- 位[0-7]:索引a
- 位[8-9]:索引b
- 位[10-15]:索引c
它们都是简单的无符号整数。我想我可能会使用位字段来获得一个很好的语法。我定义了
struct Foo {
unsigned int a : 8, b : 2, c : 6;
};
然而,我得到 sizeof(Foo) == 4
。为什么?我希望这里有一个 2 字节的结构。编译器是否在我的字段之间添加了填充?如果我使用 unsigned char
作为我的成员类型,我得到 2 个字节的大小。
在 cppreference 上,它说:
Multiple adjacent bit fields are usually packed together (although this behavior is implementation-defined).
这是否意味着我不能依赖于将字段打包在一起?最后,我将使用 memcpy
将此 struct
转换为字节流并将其写入文件。这不是很好地使用位字段吗?这只有在保证这些位被打包在一起时才有效。
编辑:实际的 header 与 GIF format 相关。许多索引都被打包成几个字节。其中一些由1、2、3或更多位组成。
来自 [class.bit]/1 [摘录]:
[...] Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined.
并且,来自 [defns.impl.defined]:
implementation-defined behavior
behavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation documents
因此,对于可移植的实现,您不能依赖任何特定类型的行为来实现 implementation-defined 行为。但是,如果您正在为特定平台和编译器开发,您 可以 在一定程度上依赖记录的 implementation-defined 行为。