Fundamental Alignment Value
Alignment is the property of a memory address. When a certain type is said to have a four byte alignment, the compiler, linker and the built-in allocation functions of C++ will allocate objects on memory addresses that are properly aligned for that type. The new proposal introduces two concepts: fundamental alignment and extended alignment. A fundamental alignment is represented by an alignment value less than or equal to the greatest alignment supported by the implementation in all contexts. This value is equal to alignof(std::max_align_t). The fundamental alignment of a typical 32-bit Windows XP machine running on Intel 32-bit hardware is four bytes. An extended alignment is represented by an alignment value greater than the fundamental alignment of the target implementation. For example, Session has an extended alignment on 32-bit Windows XP.
Having introduced the necessary technical jargon, let's see first how you can detect the fundamental (i.e., default) alignment of Session. You can then use that information to decide whether you need to override the fundamental alignment explicitly.
The operator alignof(T) takes a type T as its sole argument and returns an integral constant of type std::size_t that is the alignment value of T:
cout<<"Session's fundamental alignment: "
The output will reveal the fundamental alignment of Session on your machine. It's unlikely that all target platforms will report the same value. Some platforms will display four, others might display 16 and there are also super-computers that have fundamental alignment value of 64 bytes. Now, let's see how to enforce a cross-platform uniform alignment value.
Forcing an Alignment Value
Class Session is an epicurean bed situation: it can't have an alignment that is weaker (smaller) than 16 bytes, nor can it have an alignment value that is stricter (bigger) than 16 bytes. To guarantee a 16 byte alignment value, use the alignas(n) operator. alignastakes a positive integral constant expression that indicates the desired alignment value:
alignas(16) class Session
long long timestamp;
An invalid alignment value or a value that isn't supported by the target implementation will cause a compilation error.
An expression of the form alignas(T) has the same effect as alignas(alignof(T)). Therefore, you can assign an alignment value of type T to another type U without having to guess what the alignment of T is. For example, if you want to allocate an array of char (which by default has an alignment value of 1) with an alignment value that will suit class Session, allocate the chararray like this:
unsigned char alignas(Session) buff[sizeof(Session)];
The line above declares an array of unsigned char called buff, which has the alignment requirement of class Session. This means that you can safely construct a Session object on buffalthough the array is allocated on the stack:
Session *p = new(buff) Session;
This technique solves an onerous problem from which automatic char arrays have always suffered. In C+03, there's no guarantee that a char array allocated on the stack shall have the right alignment for accommodating any other objects but char, as opposed to pointers returned from malloc() and new (the latter are fundamentally aligned to suit any type). This is why all normative examples of placement new use dynamically-allocated buffers instead of automatic arrays. With the introduction of operator alignas, it's now possible to allocate any type of objects on an automatic chararray. Hooray!