c++中的结构对齐和填充

Structure Alignment and padding in c++

本文关键字:填充 对齐 结构 c++      更新时间:2023-10-16

代码的输出是如何变化的?我知道

struct-declarator:
declarator
type-specifier declarator opt : constant-expression

这里的constant-expression以位为单位指定字段的宽度。

#include<stdio.h>
    int main()
    {
        struct value{
           int bit1 : 8;
           int bit3 : 8;
           int bit4 : 8;
           }bit;

       printf("%dn",sizeof(bit));
     return 0;
}

输出为4

#include<stdio.h>
int main()
{
    struct value{
       int bit1 : 1;
       int bit3 : 4;
       int bit4 : 4;
       }bit;

       printf("%dn",sizeof(bit));
     return 0;
}
输出4

#include<stdio.h>
    int main()
    {
        struct value{
           int bit1 : 1;
           int bit3 : 16;
           int bit4 : 16;
           }bit;

           printf("%dn",sizeof(bit));
         return 0;
    } 

输出为8

据我所知,结构体的大小是它内部声明的所有数据类型的大小。

这是由于打包和字节对齐。检查结构对中

查看C-FAQ了解详细信息

是为"对齐"设置的。许多处理器不能访问2字节和4字节的数量(例如int型和long int型),如果它们被塞满了。

假设你有这样的结构:

struct  {
    char a[3];
    short int b;
    long int c;
    char d[3];
    };

现在,你可能认为应该可以像这样将这个结构打包到内存中:

+-------+-------+-------+-------+
|           a           |   b   |
+-------+-------+-------+-------+
|   b   |           c           |
+-------+-------+-------+-------+
|   c   |           d           |
+-------+-------+-------+-------+

但是如果编译器这样安排的话,对处理器来说会容易得多:

+-------+-------+-------+
|           a           |
+-------+-------+-------+
|       b       |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           |
+-------+-------+-------+

packed'' version, notice how it's at least a little bit hard for you and me to see how the b and c fields wrap around? In a nutshell, it's hard for the processor, too. Therefore, most compilers will pad "中,结构(好像有额外的,不可见的字段)如下:

+-------+-------+-------+-------+
|           a           | pad1  |
+-------+-------+-------+-------+
|       b       |     pad2      |
+-------+-------+-------+-------+
|               c               |
+-------+-------+-------+-------+
|           d           | pad3  |
+-------+-------+-------+-------+

还可以查看C-Faq

答案是:视情况而定。该标准对位域的布局没有要求。具体地说,

类中位域的分配对象是实现定义的。位字段的对齐由实现定义。位域被打包到某个可寻址的分配单元。[注:位域在某些机器上跨分配单元,而不是。于人。位域在一些机器上从右到左分配,在其他机器上从左到右分配。-end note]

  • 假设为32位整数,每个整数的最大空间需求为3*sizeof(int),或12,12,12字节。
  • 最大包装的最小尺寸分别是3,3,4字节,这可能取决于#pragma pack
  • 典型的结果可能是4,4,8,但这很容易因编译器而异。

所以答案是:看情况而定。这就是我强烈建议不要在布局或大小要求很重要的时候使用位字段的原因之一。