BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bsls_alignedbuffer

Macros

#define bsls_AlignedBuffer   bsls::AlignedBuffer
 This alias is defined for backward compatibility.
 

Detailed Description

Outline

Purpose

Provide raw buffers with user-specified size and alignment.

Classes

See also
bsls_objectbuffer, bsls_alignmenttotype

Description

This component provides a templated buffer type with a user-specified compile-time size and user-specified alignment. The user instantiates bsls::AlignedBuffer with specific size and alignment requirements, and then uses that memory as needed. If an alignment is not specified at template instantiation, then the buffer object is maximally aligned.

Typically, bsls::AlignedBuffer is used in situations where it is desirable to allocate a block of properly-aligned raw memory from somewhere other than the heap, e.g., on the stack or within an aggregate object, including within a union. It is a convenient way to create a small heap from which one or more objects are allocated at run-time.

Single-Object Buffers

Although, for a given type T, bsls::AlignedBuffer<sizeof(T), bsls::AlignmentFromType<T>::value> will produce a buffer properly sized and aligned to hold a T object, it is simpler and clearer to use bsls::ObjectBuffer<T> for this purpose. See the bsls_objectbuffer component for more information.

Stack Alignment

On platforms with 32-bit words, there is usually no efficiency gain by using more than 4-byte alignment. Yet some compilers use 8-byte alignment for long long or double, presumably so that the code will run faster on a future 64-bit CPU. The program loader, however, has no reason to presume more than 4-byte alignment when allocating the program stack. This can result in stack objects appearing to be misaligned relative to the alignments computed by this component. This is not a bug in either this component nor in the compiler, but it is somewhat surprising. We have seen this behavior on the MS VC++ 7 platform. See also the "Surprises and Anomalies" section in bsls_alignmentfromtype.h.

Known issues

On all versions of the Microsoft compiler prior to MSVC 14.0 (2015), passing AlignedBuffer or an object containing AlignedBuffer as a by-value function argument would lead to C2719 error (see https://msdn.microsoft.com/en-us/library/373ak2y1.aspx). In versions 14.10 (2017) through 16.8 (2019) it can trigger a compiler bug leading to crashes due to the destructor being invoked with an incorrect this pointer. This bug has been observed only building for x86 (32-bit) platform in Debug mode (specifically with /Od /Ob0 flags), e.g.:

struct X {
};
void func(X) {}
int main()
{
func(X()); // The destructor of 'X' is called with broken 'this'.
}
Definition bsls_alignedbuffer.h:261

See DRQS 151904020 for more details.

This was fixed my Microsoft in MSVC 2019 version 16.9, for details see: https://developercommunity.visualstudio.com/t/incorrect-code-gen-missing-error/831543

Usage

The allocateFromBuffer function below uses an aligned buffer as a small heap from which objects can be allocated. We choose int alignment (4-byte alignment) for our buffer because the objects we are allocating are composed of char, short, and int values only. If no alignment were specified, the buffer would be maximally aligned, which could be wasteful on some platforms.

const int MY_ALIGNMENT = bsls::AlignmentFromType<int>::value;
const char* my_AllocEnd = my_AllocBuffer.buffer() + 1000;
char *my_AllocPtr = my_AllocBuffer.buffer();
// Invariant: my_AllocPtr is always aligned on a multiple of 4 bytes
static void *allocateFromBuffer(int size)
{
if (size > my_AllocEnd - my_AllocPtr)
return 0; // Out of buffer space
void *result = my_AllocPtr;
my_AllocPtr += size;
if (size % MY_ALIGNMENT) {
// re-establish invariant by re-aligning my_AllocPtr
my_AllocPtr += MY_ALIGNMENT - size % MY_ALIGNMENT;
}
assert(0 == size_t(my_AllocPtr) % MY_ALIGNMENT); // Test invariant
return result;
}
char * buffer()
Definition bsls_alignedbuffer.h:294
Definition bsls_alignmentfromtype.h:376

Below, we use our allocation function to allocate arrays of char, short, and user-defined Object types from the static buffer. Note that our Object structure is composed of members that have alignment requirements less than or equal to ints alignment requirements.

struct Object {
char d_c;
short d_s;
int d_i;
};
int main()
{
// Allocate three 'char's from the buffer.
char *charPtr = (char *) allocateFromBuffer(3 * sizeof(char));
assert(0 == size_t(charPtr) % MY_ALIGNMENT);
// Allocate three 'short's from the buffer.
short *shortPtr = (short *) allocateFromBuffer(3 * sizeof(short));
assert(0 == size_t(shortPtr) % MY_ALIGNMENT);
// Allocate three 'Object's from the buffer
Object *objPtr = (Object *) allocateFromBuffer(3 * sizeof(Object));
assert(0 == size_t(objPtr) % MY_ALIGNMENT);
if (!charPtr || !shortPtr || !objPtr) {
fprintf(stderr, "Global buffer is not large enough.\n");
return -1;
}
// ...
return 0;
}

Macro Definition Documentation

◆ bsls_AlignedBuffer

#define bsls_AlignedBuffer   bsls::AlignedBuffer