While thinking of a counter-example for this question, I came up with:
struct A
{
alignas(2) char byte;
};
But if that's legal and standard-layout, is it layout-compatible to this struct B
?
struct B
{
char byte;
};
Furthermore, if we have
struct A
{
alignas(2) char x;
alignas(4) char y;
};
// possible alignment, - is padding
// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
// x - - - y - - - x - - - y - - -
struct B
{
char x;
char y;
}; // no padding required
union U
{
A a;
B b;
} u;
Is there a common initial sequence for A
and B
? If so, does it include A::y
& B::y
? I.e., may we write the following w/o invoking UB?
u.a.y = 42;
std::cout << u.b.y;
(answers for C++1y / "fixed C++11" also welcome)
See [basic.align] for alignment and [dcl.align] for the alignment-specifier.
[basic.types]/11 says for fundamental types "If two types
T1
andT2
are the same type, thenT1
andT2
are layout-compatible types." (an underlying question is whetherA::byte
andB::byte
have layout-compatible types)[class.mem]/16 "Two standard-layout struct 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."
[class.mem]/18 "Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members."
[class.mem]/18 "If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them."
Of course, on a language-lawyer level, another question is what it means that the inspection of the common initial sequence is "permitted". I guess some other paragraph might make the above u.b.x
undefined behaviour (reading from an uninitialized object).
int
and achar
hasint
alignment. Thatalignas(2)
attribute forchar byte
as a first element is a no-op because that first element already hasalignas(int)
alignment. A possibly better example:struct A {int x; alignas(double) char byte;};
– David Hammenalignas
on its members is not intended to be standard-layout, thensizeof(A)
could be four, with the second member at offset 0, and the first at offset 2. Somewhat more relevant note: the current wording of "standard-layout" that already makes the literal requirements unimplementable for other reasons. Details here. I looked for open issues regarding alignment too, but found nothing of interest. – user743382union
s. – dyp