C++ 未指定结构的编译器重新排序

C++ 未指定结构的编译器重新排序,c++,c,C++,C,我希望这个结构的大小是40字节。但编译器返回了32个字节。 我期待下面的布局 [char f][7 bytes][double dd][int data][4 bytes][char c][7 bytes][double d]=40 这是基于结构及其成员变量将与当前最大大小的数据类型对齐的规则 但看起来编译器重新排序了未命名的结构。是这样吗?为什么是32字节?规则不是每个结构成员必须根据结构中成员的最大对齐要求对齐。规则是每个成员必须根据其自身的对齐要求对齐 对于您的结构,假设char、int和

我希望这个结构的大小是40字节。但编译器返回了32个字节。 我期待下面的布局

[char f][7 bytes][double dd][int data][4 bytes][char c][7 bytes][double d]=40

这是基于结构及其成员变量将与当前最大大小的数据类型对齐的规则


但看起来编译器重新排序了未命名的结构。是这样吗?为什么是32字节?

规则不是每个结构成员必须根据结构中成员的最大对齐要求对齐。规则是每个成员必须根据其自身的对齐要求对齐

对于您的结构,假设
char
int
double
的大小分别为1、4和8字节,并且假设它们的对齐要求也为1、4和8字节,典型C实现中的布局为:

  • charf
    位于偏移量0处
  • 七个字节的填充将偏移量增加到8,这是双精度
    所需的
  • 双dd
    位于偏移量8处
  • struct
    从偏移量16开始
  • int data
    位于偏移量16处
  • 字符c
    位于偏移量20处
  • 三个字节的填充将ofset设置为24,这是双精度
    所需的
  • 双d
    位于偏移量24处

这使得总大小为32字节。因为这是8的倍数,所以末尾不需要填充。(由于结构可用于阵列中,因此结构的总尺寸需要是其对齐要求的倍数,以便阵列中的连续结构位于所需的对齐边界上。)

规则不是每个结构构件必须按照结构中构件的最大对齐要求对齐。规则是每个成员必须根据其自身的对齐要求对齐

对于您的结构,假设
char
int
double
的大小分别为1、4和8字节,并且假设它们的对齐要求也为1、4和8字节,典型C实现中的布局为:

  • charf
    位于偏移量0处
  • 七个字节的填充将偏移量增加到8,这是双精度
    所需的
  • 双dd
    位于偏移量8处
  • struct
    从偏移量16开始
  • int data
    位于偏移量16处
  • 字符c
    位于偏移量20处
  • 三个字节的填充将ofset设置为24,这是双精度
    所需的
  • 双d
    位于偏移量24处

这使得总大小为32字节。因为这是8的倍数,所以末尾不需要填充。(由于结构可用于阵列中,因此结构的总尺寸需要是其对齐要求的倍数,以便阵列中的连续结构位于所需对齐边界上。)

该假设是错误的。编译器没有对其重新排序。这可以用
[char f][7 bytes][double dd][int data][char c][3 bytes][double d]=32
来解释。编译器不会将每个成员与给定数据类型的最大对齐方式对齐。每个类型都有一个对齐方式,并且必须与该对齐方式对齐。对于像AFAIK这样的基本类型,它们的对齐是它们的大小—在结构实例中测试单个元素的地址,或者在调试器和视图内存中逐步执行。另见。@tadman见,too@justin:这应该是一个答案。在一个旧的线程中,进一步阅读这里的假设是错误的。编译器没有对其重新排序。这可以用
[char f][7 bytes][double dd][int data][char c][3 bytes][double d]=32
来解释。编译器不会将每个成员与给定数据类型的最大对齐方式对齐。每个类型都有一个对齐方式,并且必须与该对齐方式对齐。对于像AFAIK这样的基本类型,它们的对齐是它们的大小—在结构实例中测试单个元素的地址,或者在调试器和视图内存中逐步执行。另见。@tadman见,too@justin:这应该是一个答案。在一个旧的线程中进一步阅读
struct unaming
{
    char f;
    double dd;

    struct 
    {
    int data;
    char c;
    double d;
    };
};