2

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?

Community
  • 1
  • 1
Curious
  • 20,870
  • 8
  • 61
  • 146
  • If you are going to ask *Is there a portable way in C++[...]* why tag the question with C? – NathanOliver Feb 09 '17 at 15:07
  • @NathanOliver my mistake... – Curious Feb 09 '17 at 15:08
  • @nwp but won't the alignment be the same as the largest datatype in the struct? – Curious Feb 09 '17 at 15:14
  • @nwp Ah, any way I can change the alignment of the struct to be 16 then? I guess the alignment for any datatype (class or struct) then is going to be the largest primitive alignment required on the system? – Curious Feb 09 '17 at 15:16
  • @nwp because the `alignas` keyword does that right? Then there must be a way to do that without using `alignas` also? – Curious Feb 09 '17 at 15:19
  • 1
    Are you looking for `std::max_align_t`, by any chance? – Igor Tandetnik Feb 09 '17 at 15:21
  • If you read the documenation **carefully**. you might find the type dedicated to this. – too honest for this site Feb 09 '17 at 15:21
  • Wait, maybe I was talking garbage. `alignas` should tell the compiler that `SomethingElse` is 16-byte aligned. That makes the largest member of whatever has a `SomethingElse` also at least 16 bytes. I do remember a caveat that neither `malloc` nor `new` are required to actually give you over-aligned memory though. Not sure if that got fixed. – nwp Feb 09 '17 at 15:21
  • @nwp how even would one go about fixing that? There is no way to tell malloc the alignment that you want right? – Curious Feb 09 '17 at 15:23
  • @IgorTandetnik Thanks! And yes Olaf I should have read documentation more carefully, I would have seen it. – Curious Feb 09 '17 at 15:24
  • @IgorTandetnik Do you want to post an answer so that I can accept it? – Curious Feb 09 '17 at 15:24
  • `malloc` might already give you 16-byte aligned memory for efficiency reasons. Otherwise you are kind of screwed. Writing a wrapper that returns properly aligned memory by allocating more than necessary will work fine, but `free`ing that memory is not so easy because you need to restore the original pointer which you will need to keep somewhere. – nwp Feb 09 '17 at 15:27
  • As a sidenote: you want the **maximum** alignment requirement, not the minimum. – too honest for this site Feb 09 '17 at 15:38
  • @Olaf i meant "minimum alignment requirement that doesn't cause a fault" – Curious Feb 09 '17 at 15:39
  • 1
    @Curious: Which would be the _maximum_ alignment **requirement**! Which is reflected by the name of the type, which does not read `min_align_t` (that would be `char` by definition). – too honest for this site Feb 09 '17 at 15:41
  • 1
    @Curious `There is no way to tell malloc the alignment that you want right?` Right, but you can tell `std::aligned_alloc` when that is available. – eerorika Feb 09 '17 at 16:00

2 Answers2

3

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.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • According to [aligned_alloc](http://en.cppreference.com/w/c/memory/aligned_alloc) reference, it's part of C++11 (or I don't understand the meaning of "(since C11)" correctly). – Rotem Feb 09 '17 at 18:26
  • @Rotem C11 is a C language standard :) cppreference is a refrence for both C and C++. – eerorika Feb 09 '17 at 19:19
2

You might be looking for std::max_align_t

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85