gpt4 book ai didi

c++ - 继承中的内存对齐规则

转载 作者:太空狗 更新时间:2023-10-29 22:54:05 25 4
gpt4 key购买 nike

我试图弄清楚类对齐在继承的情况下是如何工作的。目前我的理解是

  • 该类将具有其最宽成员的对齐方式
  • 类的末尾可以根据其对齐方式进行填充,以防它在数组中
  • 结构成员根据结构对齐方式对齐

例如:

struct Nested { // Due to the long long element it is 8 aligned
short int ShortNestedElement; //6 bytes of padding here
long long int LongNestedElement;
};

struct Example {
short int ExampleMember_1; // 6 bytes of padding here
Nested ExampleMember_2;
char ExampleMember_2; // 7 bytes of padding here
};

我的困惑来自于继承:

struct Base1 {
short unsigned int Base_1Member_1;
long unsigned int Base_1Member_2;
};

struct Base2 {
unsigned int Base_2Member_1;
};


struct Base4 {
unsigned int Base_4Member_1;
};

struct Base3 : Base4 {
long unsigned int Base_3Member_1;
};

struct Final: Base1, Base2, Base3 {
};

根据 clang 类 Final 的布局是:

*** Dumping AST Record Layout
0 | struct Final
0 | struct Base1 (base)
0 | unsigned short Base_1Member_1
8 | unsigned long Base_1Member_2
16 | struct Base2 (base)
16 | unsigned int Base_2Member_1
24 | struct Base3 (base) --------> ?
24 | struct Base4 (base)
24 | unsigned int Base_4Member_1
32 | unsigned long Base_3Member_1
| [sizeof=40, dsize=40, align=8,
| nvsize=40, nvalign=8]

我不明白为什么当我们考虑 Base3 时,即使它继承自 Base4(因此 Base4 的成员出现在 Base3 之前)我们考虑的是 Base3(8) 而不是 Base4(4) 的对齐。但是,如果我更改这两个类的内容,使 Base3 与 4 对齐,而 Base4 与 8 对齐,则它采用 Base4 的对齐方式。

它是否采用继承层次结构中最广泛的类?

最佳答案

这在很大程度上取决于实现。在您的代码中:

struct Nested { // Due to the long long element it is 8 aligned
short int ShortNestedElement; //6 bytes of padding here
long long int LongNestedElement;
};

struct Example {
short int ExampleMember_1; // 6 bytes of padding here
Nested ExampleMember_2;
char ExampleMember_2; // 7 bytes of padding here
};

long long 不必是 8 个字节,short 不必是 2 个字节,char 也不必必须是 1 个字节。如果是,则 long long 不必按 8 字节对齐,short 不必按 2 字节对齐,并且 char 不必是 1 字节对齐的。也不能保证如您的评论所示插入填充。这些都是实现定义的

现在让我们看看你的问题:

struct Base1 {
short unsigned int Base_1Member_1;
long unsigned int Base_1Member_2;
};

struct Base2 {
unsigned int Base_2Member_1;
};


struct Base4 {
unsigned int Base_4Member_1;
};

struct Base3 : Base4 {
long unsigned int Base_3Member_1;
};

struct Final: Base1, Base2, Base3 {
};

I don't understand why, when we consider Base3 even if it inherits from Base4 (so the members of Base4 comes before Base3) we consider the alignment of Base3(8) instead of Base4(4). But if I change the contents of these two classes so that Base3 is aligned to 4 and Base4 is aligned to 8 it takes the alignment of Base4.

如果Base3继承自Base4,则Base4Base3的子对象,所以对齐要求Base4 有效地传播到 Base3。因此,alignof(Base3)成为alignof(Base4)与其成员对齐要求中较大的一个。因此,实际上,它采用了“层次结构中最广泛的”。至少现实世界中的对齐方式是这样的。

同样,标准没有指定这类事情。无法保证 alignof(Base3) == std::max(alignof(Base4), alignof(unsigned long))


以后讨论对齐时,请使用alignas,而不是依赖内置类型的对齐。

关于c++ - 继承中的内存对齐规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57527550/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com