结构/对象内的存储顺序

Ami*_*mar 5 c c++ pointers structure class

考虑这两种情况:

struct customType
{
   dataType1 var1; 
   dataType2 var2;
   dataType3 var3;
} ;

customType instance1;
// Assume var1, var2 and var3 were initialized to some valid values.

customType * instance2 = &instance1;    
dataType1 firstMemberInsideStruct = (dataType1)(*instance2);
Run Code Online (Sandbox Code Playgroud)
class CustomType
{
   public:
       dataType1 member1;
       dataType2 member2;

       retrunType1 memberFunction1();

   private:
       dataType3 member3;
       dataType4 member4;

       retrunType2 memberFunction2();
};

customType object;
// Assume member1, member2, member3 and member4 were initialized to some valid values.

customType *pointerToAnObject = &object ;
dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);
Run Code Online (Sandbox Code Playgroud)

是否总是安全做到这一点?

我想知道标准是否指定了任何存储顺序 -

  1. C结构中的元素.
  2. C++类对象内的数据成员.

For*_*veR 6

9.0.7

标准布局类是一个类: - 没有类型为非标准布局类(或此类类型的数组)或引用的非静态数据成员, - 没有虚函数(10.3)且没有虚基类( 10.1), - 对所有非静态数据成员具有相同的访问控制(第11条), - 没有非标准布局基类, - 在最派生类中没有非静态数据成员,最多只有一个具有非静态数据成员的基类,或者没有具有非静态数据成员的基类,并且 - 没有与第一个非静态数据成员相同类型的基类.

9.2.14

分配具有相同访问控制(第11条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址.未指定具有不同访问控制的非静态数据成员的分配顺序(11).实施对齐要求可能导致两个相邻成员不能立即分配; 因此,可能需要空间来管理虚拟功能(10.3)和虚拟基类(10.1).

9.2.20

指向标准布局结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然.[注意:因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐. - 结束说明]


sfs*_*man 5

C99和C ++对此有所不同。

C99标准保证结构的字段按声明的顺序排列在内存中,并且两个相同结构的字段具有相同的偏移量。见这个问题为C99标准的相关章节。总结一下:第一个字段的偏移量指定为零,但此后的偏移量未由标准指定。这是为了允许C编译器调整每个字段的偏移量,以便该字段将满足体系结构的任何内存对齐要求。因为这与实现有关,所以C提供了使用offsetof宏确定每个字段的偏移量的标准方法。

C ++仅对纯旧数据(POD)提供此保证。不是普通旧数据的C ++类不能这样对待。当类使用多重继承,具有非公共字段或成员或包含虚拟成员时,该标准为C ++编译器在组织类时提供了很大的自由度。

这对您的示例意味着什么:

dataType1 firstMemberInsideStruct = (dataType1)(*instance2);
Run Code Online (Sandbox Code Playgroud)

仅当 dataType1,dataType2和dataType3是纯旧数据时,此行可以。如果其中任何一个都不存在,则customType结构可能没有琐碎的构造函数(或析构函数),并且这种假设可能不成立。

dataType1 firstMemberInTheObject = (dataType1) (*pointerToAnObject);
Run Code Online (Sandbox Code Playgroud)

无论此行是不是安全dataType1dataType2以及dataType3是POD,因为CustomType类有私有的实例变量。这使得它不是 POD类,因此您不能假定其第一个实例变量将以特定方式排序。