Provided that struct A and struct B are layout-compatible, why aren't A[N] and B[N] layout-compatible? What is the fundamental issue with it?
In the following example, accessing the first union member through the second one inside ub() results in undefined behavior. However, in ok() the behavior is well-defined.
struct A { int i; }; // A and B are
struct B { int j; }; // layout-compatible
union C { A a; B b; };
union D { A a[3]; B b[3]; };
int ok() {
C c { .a = 1 }; // ok, initialize c.a
return c.b.j; // ok, as if c.a.i were nominated
}
int ub() {
D d { .a = { 1, 2, 3 } }; // ok, initialize d.a
return d.b[0].j; // UB, A[3] and B[3] are
// not layout-compatible
}
Excerpt from the standard, [basic.types]/11 (N4861, emphasis mine):
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.
cppreference also mentions this but doesn't go into details.
Array type of layout-compatible but different element types (ignoring cv-qualification) are not layout-compatible, even if they are of equal length.