In a class without virtual methods or a superclass, is it possible to consider (address of the first member variable) == this?

I made a private API that assumes that the address of the first member element in the class will be the same as the this-pointer class ... so a member object can trivially get a pointer to the object that it is a member without having to explicitly point pointer.

Given that I am ready to make sure that the container class will not inherit from any superclass, will not have any virtual methods, and that the member object that does this trick will be the first declared object declared, this assumption is true for any C compiler ++, or do I need to use the offsetof () operator (or similar) to guarantee correctness?

In other words, the code below does what I expect under g ++, but will it work everywhere?

class MyContainer { public: MyContainer() {} ~MyContainer() {} // non-virtual dtor private: class MyContained { public: MyContained() {} ~MyContained() {} // Given that the only place Contained objects are declared is m_contained // (below), will this work as expected on any C++ compiler? MyContainer * GetPointerToMyContainer() { return reinterpret_cast<MyContainer *>(this); } }; MyContained m_contained; // MUST BE FIRST MEMBER ITEM DECLARED IN MyContainer int m_foo; // other member items may be declared after m_contained float m_bar; }; 
+4
source share
3 answers

It seems that the current standard guarantees this only for POD types.

9.2.17

A pointer to a POD-struct object, properly transformed, points to it (or if this member is a bit field, then to the block in which it is located) and vice versa. [Note: Therefore, there may be an unnamed padding in the POD-struct object, but not at the very beginning, as necessary to achieve proper alignment. ]

However, the C ++ 0x standard seems to extend this guarantee to a “standard layout structure object”

The standard layout class is a class that:

- does not contain non-static data the type of a non-standard layout (or an array of such types) or a link,

- does not have virtual functions (10.3) and there are no virtual base classes (10.1),

- has the same access control (clause 11) for all non-static data members,

- does not have a base of non-standard layout classes,

- either does not have non-static member data in the most derived class and no more than one base class with non-stationary data or does not have base classes with non-static data elements and

- does not have base classes of the same type as the first non-static data element.

The standard layout structure is the standard layout class defined using the class-key struct or class key class.

It is probably likely that the assumption is true in practice (and the first did not just have these differences, although this could be the intention)?

+5
source

This is not guaranteed for types other than POD. C ++ 9.2 / 12 standard:

Non-static data elements (nonunit) A class declared without an intermediate access specifier is used to subsequently members have higher addresses in the object class. The distribution order of non-static data elements separated by an access specifier is not specified (11.1). Alignment of the implementation requirements may result in two adjacent participants not being distributed immediately after each other; so that the space requirements for managing virtual functions (10.3) and virtual base classes (10.1).

In your case, you have a non-POD type, since it contains a custom destructor. You can read more about POD types here .

+3
source

The last draft of the C ++ specification says that it’s normal if the class qualifies as a standard layout class that only requires

  • does not have non-static data members such as a non-standard class layout (or an array of such types) or a link,
  • does not have virtual functions (10.3) and there are no virtual base classes (10.1),
  • has the same access control (section 11) for all non-static data members,
  • does not have base classes of non-standard layout,
  • either does not have non-static data elements in the derived class itself, but no more than one base class with non-static data elements or does not have base classes with non-static data elements and
  • does not have base classes of the same type as the first non-static data element.

Depending on the definition of MyContained your class may or may not be a standard layout.

Note that POD classes are the intersection of the standard layout and the trivially copied classes.

+2
source

Source: https://habr.com/ru/post/1306730/


All Articles