If I declare my class struct alignas(16) C { int x; };
, is x
guaranteed to be aligned to 16 bytes or could the compiler pad it on the “left”? What about template <typename T, std::size_t Align> struct alignas(Align) Aligned : T { using T::T; };
? Would the T
of Aligned<T, N>
be aligned to N
? Is that the right way to make a type that is a T
that is always aligned?
CodePudding user response:
If I declare my class
struct alignas(16) C { int x; };
, isx
guaranteed to be aligned to 16 bytes or could the compiler pad it on the “left”?
In this case, x
has to be on the 16 byte boundary because you have a standard layout class. A standard layout class comes with a guarantee that the first member of the class shares the same address as the class itself, meaning it will have the same alignment.
What about
template <typename T, std::size_t Align> struct alignas(Align) Aligned : T { using T::T; };
?
This is the same case as long as T
is a standard layout class. If it is then Aligned
has standard layout, and the first base class subobject is guaranteed to be at the start of the object in memory, so it has the same alignment.
Is that the right way to make a type that is a
T
that is always aligned?
It's an way. Another approach would be to use a std::aligned_storage
object and then use placement new to emplace an object into that aligned storage.