gpt4 book ai didi

c++ - 具有虚函数和动态分配的类的成员对象对齐问题

转载 作者:行者123 更新时间:2023-11-30 05:24:30 24 4
gpt4 key购买 nike

请阅读以下代码。

struct alignas(32) A
{
int a;
};
struct B
{
A a;
virtual void foo(){ cout << 'B'; }
};

struct C : public B
{
virtual void foo(){ cout << 'C'; }
};

int main()
{
A aa;
C c;
C *pc = new C;
}

“A”是一个32字节对齐的结构,所以“main”函数中的变量“aa”是32字节对齐的。但是,struct "C"是一个带有虚函数的类,所以成员对象 "a"不在类的开头。

我的第一个问题是“main”函数中的变量“c”是32字节对齐的还是它的成员对象“a”对齐的?

第二个问题是关于“main”函数中的变量“pc”。我知道“pc”的地址可能没有对齐。那么有没有一种方法可以保证成员“a”在任何情况下都对齐?

最佳答案

一般原则

根据标准:

3.11/1: Object types have alignment requirements which place restrictions on the addresses at which an object of that type may be allocated.

这些要求对类有影响:

9.2/13: Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions and virtual base classes.

因此编译器可能会在类成员之间使用填充来符合对齐要求。这只有在编译器可以对整个对象的地址做出一些假设时才有效。换句话说,成员(例如A a)的对齐要求会影响其包含类(例如struct B)的对齐要求。这同样适用于继承(例如 struct C: public B),因为继承意味着存在一个子对象(例如 B 类型的对象在 C 类型的对象中) )。

据我所知,标准中没有写编译器必须如何做才能达到要求,但提醒:

3.11/5: Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.

所以一个类的对齐要求很可能是它的基类及其所有成员的最大对齐要求。

你的具体例子

首先你可以检查多态和虚函数的效果:

struct Simple {
char x;
};
struct SimpleVirtual {
char x;
virtual ~SimpleVirtual() {}
};
...
cout<<"Simple :"<<alignof(Simple)<<endl;
cout<<"SimpleVirtual :"<<alignof(SimpleVirtual)<<endl;

你会看到 A 的 XXL 对齐要求比来自虚函数的对齐要求大得多(例如,通常用 vtable 指针实现):

 cout<<"A : "<<alignof(A)<<endl; 
cout<<"B : "<<alignof(B)<<endl;
cout<<"C : "<<alignof(C)<<endl;

在您的具体示例中,32 字节对齐被传输到所有 3 个类。

这里是online demo .

格外小心:前面的实现定义了行为!!

您的 XXL 对齐(它是字节而不是位)可能不被所有编译器支持:

3.11/3: An extended alignment is represented by an alignment greater than alignof(std::max_align_t). It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an over-aligned type.

特别是对于动态分配:

5.3.4/1 (new): It is implementation-defined whether over-aligned types are supported.

例如,这个 GCC bug repport要求更好地支持过度对齐的对象。因此,您可能遇到的对齐问题来自过度对齐,而不是来自虚函数。

关于c++ - 具有虚函数和动态分配的类的成员对象对齐问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38650310/

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