Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are structs of variables of the same type layout compatible with a struct containing an array of that type?

Are these 2 structs layout-compatible?

struct One {
    float x, y, z;
};

struct Two {
    float c[3];
};

Both contains 3 floats, so in a way, this description can be considered true (from N3797):

16 Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (3.9).

N4659 has a different text:

The common initial sequence of two standard-layout struct (Clause 12) types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types and either neither entity is a bit-field or both are bit-fields with the same width.

Two standard-layout struct (Clause 12) types are layout-compatible classes if their common initial sequence comprises all members and bit-fields of both classes (6.9).

If the answer is no, they are not layout-compatible, then: was it the intention of the committee? Maybe they do want One and Two to be layout-compatible (maybe a committee member reads this, and can clarify).


Bonus question: is it guaranteed, that sizeof(One)==sizeof(Two)?

like image 707
geza Avatar asked Jul 26 '17 16:07

geza


2 Answers

Well, no:

[...] if they have the same number of non-static data members [...]

One has three members: x, y, and z. Two has one member: c. They don't have the same number of non-static data members, therefore they aren't layout compatible.


The new wording is different but you end up at the same place. [basic.types] defines layout-compatible as:

Two types cv1 T1 and cv2 T2 are layout-compatible types if T1 and T2 are the same type, layout-compatible enumerations, or layout-compatible standard-layout class types.

[class.mem] defines layout-compatible classes are:

Two standard-layout struct types are layout-compatible classes if their common initial sequence comprises all members and bit-fields of both classes ([basic.types]).

Where the common initial sequence is:

The common initial sequence of two standard-layout struct types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types and either neither entity is a bit-field or both are bit-fields with the same width.

Here, the first member of One (float x) is not layout-compatible with the first member of Two (float c[3]), so the common initial sequence is empty.

like image 177
Barry Avatar answered Oct 19 '22 10:10

Barry


The compiler is allowed to add padding between members in a class or struct.

Array elements are in contiguous locations.

They may not be layout compatible depending on how the compiler organizes the members in the struct.

like image 35
Thomas Matthews Avatar answered Oct 19 '22 11:10

Thomas Matthews