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.