Aligning bytes in VS2013

February 16, 2015

In some situations where fine-grained control over memory is required, we must be careful about how we pack bytes into memory. These alignment issues can arise e.g. with particular kinds of processors or when crafting low-level input/output for hardware.

C++11 offers the alignof/alignas operators (OpenSTD) but unfortunately they are not implemented in the Visual Studio 2013 compiler (VS2013). It is possible to lean on std::align, however (CPP Align).

Suppose we have a 32 byte region of memory, and we need to always align our entries along 8-byte boundaries. In the example, we use up the first 9 bytes of the memory:

#define MEM_SIZE 32
#define HEADER "\x01\x02\x03\x04\x05\x06\x07\x08\x09"
#define HEADER_LENGTH 9

char data[MEM_SIZE] = { 0 };
memcpy(data, HEADER, HEADER_LENGTH);

Our data buffer looks like this:

db1

The next region of data needs to be aligned at an 8 byte boundary (i.e. at the 16th byte), and we can lean on std::align:

#define ALIGNMENT 8
#define BUFFER "\x10\x11\x12\x13\x14\x15\x16\x17"
#define BUFFER_LENGTH 8

void *endOfHeader = &(data[0]) + HEADER_LENGTH;
std::size_t space = MEM_SIZE - HEADER_LENGTH;
void *nextAvailableByte = std::align(ALIGNMENT, BUFFER_LENGTH, endOfHeader, space);
memcpy(nextAvailableByte, BUFFER, BUFFER_LENGTH);

std::align takes four arguments:

  1. The size of the alignment (in our case, 8 bytes)
  2. length of the data you’d like to write (in our case, also 8 bytes)
  3. The (possibly mis-aligned) pointer to the next valid address to write buffer to
  4. How much space is left in data. If std::align cannot find a spot to insert into data, it will return a null pointer (i.e. there was not enough space left, as BUFFER_LENGTH was too large). The result of our memcpy is BUFFER copied nicely along our 8 byte boundary:

db2

A complete example is available on github.