Given the following C++ class:
class X {
public:
uint8_t a;
uint32_t b[256] __attribute__((aligned(32)));
};
How can the compiler ensure that the storage for b
is 32-byte aligned, when an instance of X
is presumably word-aligned? Does the aligned
attribute only specify alignment relative to the object instance start address? If so, what is the right way to make b
32-byte aligned relative to the address space? Should I simply specify object instance alignment using using class alignof(32) X {...}
?
The standard says following:
A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to alignof(std::max_align_t) ([support.types]). The alignment required for a type may be different when it is used as the type of a complete object and when it is used as the type of a subobject. [Example 1:
struct B { long double d; }; struct D : virtual B { char c; };
When D is the type of a complete object, it will have a subobject of type B, so it must be aligned appropriately for a long double. If D appears as a subobject of another object that also has B as a virtual base class, the B subobject might be part of a different subobject, reducing the alignment requirements on the D subobject. — end example]
And [dcl.align/5]:
The combined effect of all alignment-specifiers in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all alignment-specifiers appertaining to that entity were omitted.
[Example 1: struct alignas(8) S {}; struct alignas(1) U { S s; }; // error: U specifies an alignment that is less strict than if the alignas(1) >were omitted. — end example]
So, from the above section (especially the explanations of the examples) it can be assumed that the alignment of an object is resolved to the strictest amongst its members.
class X {
public:
uint8_t a;
alignas(32) uint32_t b[256];
};
int main() {
X x1;
// alignas(16) X x; // Clang error: requested alignment is less than minimum alignment of 32 for type 'X'
alignas(64) X x2; // OK
alignof(X); // 32
alignof(x1); //32
alignof(x2); //64
alignof(x2.b); //32
return 0;
}