c++ - 相同类型的类成员之间的填充总是相同的吗?

标签 c++ class struct padding

下面的类包含一些相同类型的成员:

template <typename T>
class MyClass
{
    T m0;
    T m1;
    T m2;
    T m3;
    T m4;
    //...
};

成员都是在没有中间访问说明符的情况下声明的,因此分配给后面的成员具有更高的地址(ISO/IEC 14882:9.2.12)。同段说:

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 (10.3) and virtual base classes (10.1).

现在让我们假设 MyClass 没有虚函数,也没有虚基类。以下总是正确的吗?

//inside a member function of MyClass

(char*)&m0 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 0
(char*)&m1 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 1
(char*)&m2 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 2
(char*)&m3 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 3
(char*)&m4 == (char*)&m0 + ((char*)&m1-(char*)&m0) * 4

或者是否允许编译器使用比所需的任意更多的填充(无论出于何种原因......)?例如:如果 sizeof(T)==4 和 alignof(T)==8,编译器将在成员之间使用 4 个填充字节。仅在 m2 和 m3 之间使用 12 个填充字节是否有效?

MyClass有虚函数或虚基类时怎么办?编译器真的允许在任意数据成员之间插入与 MyClass 相关的信息(如 vtable-ptr)吗?还是上面标准中的句子与 T 的虚函数和虚基类更相关?因为如果在 T 之外存储与 T 相关的信息是有效的,那么它也可能具有以下含义:

template <typename T>
class MyClass
{
    T m0;
    //space to manage virtual functions and base classes of m0
    //padding
    T m1;
    //space to manage virtual functions and base classes of m1
    //padding
    T m2;
    //space to manage virtual functions and base classes of m2
    //...
};

什么又可以给出一个规则的模式。

最佳答案

没有。没有规则强制要求它,因此编译器可以在任何地方插入填充。 “对齐要求可能……”只是一个例子,并不限制可能的原因。

如果你有一个 T m[5] 成员,情况就不同了,在这种情况下 &(this->m[1]) - &(this->m [0]) == 1

出于同样的原因,“编译器真的允许在任意数据成员之间插入与 MyClass 相关的信息(如 vtable-ptr)吗?”必须正面回答,因为没有禁止的规则。它无法将其插入子对象的中间(无论是 T 还是 T[5]),但在子对象之间没问题。

关于c++ - 相同类型的类成员之间的填充总是相同的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3140096/

相关文章:

c++ - 简化 const 重载?

c# - 在C#中实现接口(interface)时如何传递子类参数?

c++ - 图形专用模板类

c++ - 如何在 C++ 中使用结构列表

C++ 嵌入 lua 5.2 对 `luaL_newstate' 的 undefined reference (ubuntu 14.04,Netbeans)

c++ - 永远运行 boost asio io_service

go - 包含嵌入的结构 slice 的结构

C、表达式必须是可修改的左值(改变结构成员的值)

c++ - 根据给定标准的最大总和

c# - 如何让 Windows 窗体应用程序与类(class)一起工作?