Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is 'this' guaranteed to point to the start of an object in C++?

Tags:

c++

I want to write an object into a sequential file using fwrite. The Class is like

class A{
    int a;
    int b;
public:
    //interface
}

and when I write an object into a file. I am wandering that could I use fwrite( this, sizeof(int), 2, fo) to write the first two integers.

Question is: is this guaranteed to point to the start of the object data even if there may have a virtual table exist in the very beginning of the object. So the operation above is safe.

like image 420
Joey.Z Avatar asked May 29 '13 06:05

Joey.Z


People also ask

What is a pointer to object type in C?

In C++, a pointer holds the address of an object stored in memory. The pointer then simply “points” to the object. The type of the object must correspond with the type of the pointer. type *name; // points to a value of the specified type.

What is a pointer to an object?

A pointer is a type of variable that carries location information. In this case, the example variable will store the address of an Order object that we want to interact with. We initialize the pointer variable by using the C++ new operator to construct a new object of type Order.

Can you determine whether P points to a valid object?

No, you can't.

Can object be created in C?

In terms of C programming, an object is implemented as a set of data members packed in a struct , and a set of related operations. With multiple instances, the data for an object are replicated for each occurrence of the object.


1 Answers

this provides the address of the object, which is not necessarily the address of the first member. The only exception are so-called standard-layout types. From the C++11 Standard:

(9.2/20) A pointer to a standard-layout struct object, suitably converted using a reinterpret_cast, points to its initial member (or if that member is a bit-field, then to the unit in which it resides) and vice versa. [ Note: There might therefore be unnamed padding within a standard-layout struct object, but not at its beginning, as necessary to achieve appropriate alignment. — end note ]

This is the definition of a standard-layout type:

(9/7) A standard-layout class is a class that:
— has no non-static data members of type non-standard-layout class (or array of such types) or reference,
— has no virtual functions (10.3) and no virtual base classes (10.1),
— has the same access control (Clause 11) for all non-static data members,
— has no non-standard-layout base classes,
— either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
— has no base classes of the same type as the first non-static data member.[108]

[108] This ensures that two subobjects that have the same class type and that belong to the same most derived object are not allocated at the same address (5.10).

Note that the object type does not have to be a POD – having standard-layout as defined above is sufficient. (PODs all have standard-layout, but in addition, they are trivially constructible, trivially movable and trivially copyable.)

As far as I can tell from your code, your type seems to be standard-layout (make sure access control is the same for all non-static data members). In this case, this will indeed point to the initial member. Regarding using this for the purposes of serialization, the Standard actually says explicitly:

(9/9) [ Note: Standard-layout classes are useful for communicating with code written in other programming languages. Their layout is specified in 9.2. — end note ]

Of course this does not solve all problems of serialization. In particular, you won't get portability of the serialized data (e.g. because of endianness incompatibility).

like image 178
jogojapan Avatar answered Oct 20 '22 04:10

jogojapan