Say, I have an aligned array
alignas(X) char arr[sizeof(X)];
Is the pointer
X * ptr = reinterpret_cast<X*>(arr);
guaranteed to be properly aligned according to the alignment requirements of X
?
It seems obvious that this is the case, however it does not appear to be obvious from the C++ standard.
I don't find anything in the standard that would prevent a compiler to align a struct of the form
struct X
{
int16_t a;
int32_t b;
int16_t c;
};
like this in memory:
+-+-+-+-+-+-+-+-+
|a|a|b|b|b|b|c|c|
+-+-+-+-+-+-+-+-+
^
aligned to 32-boundary
so that the objects of type X
are aligned in such a way that no padding is needed and b
is aligned correctly at the same time to a 32-bit boundary. The statement (N4713, § 6.6.5.1)
An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated.
is not violated by that and I don't see any other statement in the standard that violates it.
Your structure should have an exotic alignment: it should be 16 bit aligned but not 32 aligned. Mathematically speaking, its address should be of the form 32*n+16, with n an integer.
This is forbidden by the language, a 32 bit alignment should satisfy a 16 bit alignment. Said differently any 16bit aligned structure should fit in a 32 bit aligned storage region, but your 16bit aligned structure don't. See [basic.align]/5:
Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
The authors of the Standard didn't seek to explicitly prohibit things they thought were impossible. If one compilation units contains a structure like the one you gave:
struct {
uint16_t a;
uint32_t b;
uint16_t c;
} x;
and a compiler isn't omniscient about all the ways that x
or structures with identical layout might be used throughout the rest of the program, it will have no choice but to make the offset of b
be a multiple of b
's alignment. I don't think the Standard explicitly says that the layout of a structure cannot be observably affected by the ways in which it is used, but I think that's because they didn't think a compiler where layouts could vary in that fashion would be able to uphold the Common Initial Sequence guarantees.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With