user14757101
user14757101

Reputation: 87

C++ structs/classes members

I have a couple of questions regarding the nitty-gritty of c++ struct/classes.

i) In C++, can struct members with different access modifier be reordered by the compiler? As per here, compiler can reorder members with different access. If that is the case then How do we guarantee members are correctly initialized? For e.g.

Struct S {  
private:
    int a;
public:
    int b;
S() : a(1), b(a) {}
}

If compiler can rearrange a and b then b can take any arbitrary value, isn't it?

ii) Let's consider the struct

Struct S {  
private:        int a;
public:        int b;
}

If we serialize this struct and read it in another program, could it fail if the ordering of the members is not guaranteed?

iii) In C, we can use the struct pointer and cast it to the pointer of its first data member. Could we do the same in C++? Are there any restrictions and what about reordering in that situation?

There are other posts on SO that discuss class member reordering but it's still not clear to me whether this is allowed and done by the compiler.

Thanks

Upvotes: 3

Views: 92

Answers (1)

Dietmar Kühl
Dietmar Kühl

Reputation: 153810

With respect to your first question: the order of members in memory is only guaranteed without intervening access specifier. However, the order in memory does not affect the construction or destruction order.

Assuming you actually serialize the data, the memory organization clearly doesn’t matter. Of course, simply taking the bytes in memory for the struct doesn’t really do proper serialization. In particular, there are no guarantees on how values are actually represented and size and endianess of built-in types are well-know variations. Also, potential padding needs to be taken into account. ... and, of course, possibly reordered members.

I strongly recommend to not just write the bytes! I have seen more than large company struggling massively with developers having taken that approach: any successful software will grow and outlive the immediate context and these short-cuts become massively harmful! I have seen some people who thought it is clever to effectively store important data in databases by memcpy()ing them into a blob (Binary Large OBject): aside from not being accessible to queries the data becomes easily lost if anything changes.

For C-like structs or classes, i.e., for standard-layout types (PODs in the past), the same rule applies: the address of the object is the address of the first member. If you use certain C++ constructs (inheritance, virtual functions, access specifiers, or structors and possibly others I’m forgetting) this guarantee does not apply any longer.

Upvotes: 1

Related Questions