How to tell the maximum data alignment requirement in C++

1.1k Views Asked by At

Referencing this question and answer Memory alignment : how to use alignof / alignas? "Alignment is a restriction on which memory positions a value's first byte can be stored." Is there a portable way in C++ to find out the highest granularity of alignment that is required for instructions not to fault (for example in ARM)? Is alignof(intmax_t) sufficient since its the largest integer primitive type?

Further, how does something in malloc align data to a struct's boundaries? For example if I have a struct like so

alignas(16) struct SomethingElse { ... };

the SomethingElse struct is required to be aligned to a boundary that is a multiple of 16 bytes. Now if I request memory for a struct from malloc like so

SomethingElse* ptr = malloc(sizeof(SomethingElse));

Then what happens when malloc returns a pointer that points to an address like 40? Is that invalid since the pointer to SomethingElse objects must be a multiple of 16?

2

There are 2 best solutions below

0
On BEST ANSWER

You might be looking for std::max_align_t

2
On

How to tell the maximum data alignment requirement in C++

There is std::max_align_t which

is a POD type whose alignment requirement is at least as strict (as large) as that of every scalar type.

Vector instructions may use array operands that require a higher alignment than any scalar. I don't know if there is a portable way to find out the the upper bound for that.

To find the alignment requirement for a particular type, you can use alignof.


Further, how does something in malloc align data to a struct's boundaries?

malloc aligns to some boundary that is enough for any scalar. In practice exactly the same as std::max_align_t.

It won't align correctly for "overaligned" types. By overaligned, I mean a type that has higher alignment requirement than std::max_align_t.

Then what happens when malloc returns a pointer that points to an address like 40?

Dereferencing such SomethingElse* would be have undefined behaviour.

Is that invalid since the pointer to SomethingElse objects must be a multiple of 16?

Yes.


how even would one go about fixing that? There is no way to tell malloc the alignment that you want right?

To allocate memory for overaligned types, you need std::aligned_alloc which is to be introduced in C++17.

Until then, you can use platform specific functions like posix_memalign or you can over allocate with std::malloc (allocate the alignment - 1 worth of extra bytes), then use std::align to find the correct boundary. But then you must keep track of both the start of the buffer, and the start of the memory block separately.