简体   繁体   English

C结构中的位域表达式

[英]Bit-field expression in C structure

I found a code segment for a structure as below:我找到了一个结构的代码段,如下所示:

    struct
    {
      __u8 saveable: 1;
      __u8 namespace: 1;
      __u8 changeable: 1;
      __u32 reserved: 29;
    };

I wonder what the difference is between that and the definition as below:我想知道这和下面的定义有什么区别:

    struct
    {
      __u32 saveable: 1;
      __u32 namespace: 1;
      __u32 changeable: 1;
      __u32 reserved: 29;
    };

Are there any possible reasons behind this?这背后有什么可能的原因吗?

Although the allocation of objects that contain bit-fields is implementation-defined, the C Standard does specify that consecutive bit-field members of a structure shall be packed into the same 'unit', if sufficient space remains in that unit.尽管包含位域的对象的分配是实现定义的,但 C 标准确实规定了结构的连续位域成员应打包到相同的“单元”中,如果该单元中有足够的空间。

From this Draft C11 Standard (bold emphasis mine):这个 C11 标准草案(我的粗体强调):

6.7.2.1 Structure and union specifiers 6.7.2.1 结构和联合说明符


11 An implementation may allocate any addressable storage unit large enough to hold a bit-field. 11 实现可以分配任何大到足以容纳位字段的可寻址存储单元。 If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。 If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined.如果剩余空间不足,则将不适合的位域放入下一个单元还是与相邻单元重叠是实现定义的。 The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.单元内位域的分配顺序(高位到低位或低位到高位)是实现定义的。 The alignment of the addressable storage unit is unspecified.可寻址存储单元的 alignment 未指定。

Thus, in your first structure, the first three fields could be packed into one 8-bit unit but, then, the fourth must be placed in a separate, 32-bit unit (which will likely require 4-byte alignment, thus increasing the overall size of the structure to 8 bytes).因此,在您的第一个结构中,前三个字段可以打包到一个 8 位单元中,但是第四个字段必须放在一个单独的 32 位单元中(这可能需要 4 字节 alignment,从而增加结构的总大小为 8 个字节)。 What also may be significant in such a case is that padding bytes will be added to the structure, which may cause issues if your code relies on contiguous bits.在这种情况下也可能很重要的是填充字节将添加到结构中,如果您的代码依赖于连续位,这可能会导致问题。

However, in the second case, all four bit-fields can be placed in a single 32-bit unit, so the structure size can be reduced to just 4 bytes.然而,在第二种情况下,所有四个位域都可以放在一个32 位单元中,因此结构大小可以减少到只有 4 个字节。

But note that this may vary between compilers and platforms – notably, as demonstrated in the Compiler Explorer example linked in the comments , an implementation is entitled to allocate a 32-bit unit for the first three members of the first structure.但请注意,这可能因编译器和平台而异——值得注意的是,如注释中链接的编译器资源管理器示例所示,实现有权为第一个结构的前三个成员分配一个 32 位单元。

On Windows, using the clang-cl compiler in Visual Studio 2022, I get the aforementioned size difference between the structures when compiling and running the following code:在 Windows 上,使用 Visual Studio 2022 中的 clang-cl 编译器,在编译和运行以下代码时,我得到了上述结构之间的大小差异:

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

struct {
    uint8_t saveable : 1;
    uint8_t namespace : 1;
    uint8_t changeable : 1;
    uint32_t reserved : 29;
} s1;

struct {
    uint32_t saveable : 1;
    uint32_t namespace : 1;
    uint32_t changeable : 1;
    uint32_t reserved : 29;
} s2;

int main()
{
    printf("Size of s1 = %zu\n", sizeof(s1));
    printf("Size of s2 = %zu\n", sizeof(s2));
    return 0;
}

Output: Output:

Size of s1 = 8
Size of s2 = 4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM