|
BDE 4.14.0 Production release
|
Typedefs | |
| typedef bsls::AlignmentUtil | bsls_AlignmentUtil |
| This alias is defined for backward compatibility. | |
Provide constants, types, and operations related to alignment.
This component defines a struct, bsls::AlignmentUtil, which serves as a namespace for compile-time constants, types, and operations associated with alignment on the current platform.
The BSLS_MAX_ALIGNMENT enumerator provides the minimal value that satisfies the alignment requirements for all types on the current platform. Additionally, the MaxAlignedType typedef specifies a primitive type that requires an alignment of BSLS_MAX_ALIGNMENT.
The calculateAlignmentFromSize function calculates a usable (but not necessarily minimal) alignment for any object with a memory footprint of the specified size (in bytes). The calculateAlignmentOffset function calculates the offset from a specified address where an object having a specified alignment requirement can be constructed safely. The is2ByteAligned, is4ByteAligned, and is8ByteAligned functions each return true if a specified address is, respectively, 2-, 4-, or 8-byte aligned. Finally, roundUpToMaximalAlignment returns the smallest whole multiple of BSLS_MAX_ALIGNMENT greater than or equal to its argument.
The functionality in this component makes several assumptions:
T evenly divides sizeof(T), which implies that the required alignment for T is never larger than sizeof(T).struct, class, or union is the same as the required alignment of its most restrictive non-static data member (including the implicit virtual table pointer in polymorphic classes and internal pointers in virtually-derived classes).A sequential memory allocator is used to return a sequence of memory blocks of varying requested sizes from a larger chunk of contiguous memory. Each block returned must also have an alignment that is sufficient for any conceivable object of that size. To achieve a fully factored implementation, we might choose to provide a low-level helper function naturallyAlign that, given the address of the next available byte in the larger chunk along with the requested block size (in bytes), returns the first appropriately (or naturally) aligned address for the requested block at or after address:
We can implement the naturallyAlign helper function easily using the methods defined in this class:
We will then be able to use this naturallyAlign helper function to allocate, from a buffer of contiguous memory, efficiently (but not necessarily optimally) aligned memory for objects of varying sizes based solely on the size of each object (i.e., determined by its natural, not actual, alignment).
To illustrate the functionality provided in this component, we begin by assuming that we have some user-defined type, MyType, comprising several data members:
We then define a function, f, which starts off by creating a maximally aligned buffer on the program stack:
Next we use the bsls::AlignmentUtil functions directly to confirm that buffer is sufficiently aligned to accommodate a MaxAlignedType object:
Below we perform various memory allocations using our naturallyAlign helper function:
Note that the address held in shortPtr is numerically divisible by the alignment of a short on the current platform:
Next we use naturallyAlign to allocate a block of appropriate size and sufficient alignment to store a MyType object:
Note that the alignment of the address held in objPtr is numerically divisible by the actual alignment requirement:
Assuming buffer has sufficient capacity, and the alignments for char, short, and MyType are, respectively, 1, 2, and 8, we would expect this layout within buffer.d_buffer:
Note that on an atypical 32-bit platform where a double is 4-byte aligned, the actual alignment of MyType would be 4, but its natural alignment would still be 8 because its size would be 16; it is highly unlikely that MyType would have an actual (and therefore natural) alignment of 4 on a 64-bit platform when using default compiler settings.