Struggling with alignas syntax
Asked Answered
L

1

8

I am trying to use alignas for pointers that are class members, and frankly I am not sure where I supposed to put it.

For instance:

class A
{
private:
    int n;
    alignas(64) double* ptr;    

public:
    A(const int num) : n(num), ptr(new double[num])
    {}
};

which I hoped would ensure the data for ptr was aligned on a 64-byte block. Using the Intel compiler, it doesn't.

Can anyone point me in the right direction please?

Lucie answered 17/12, 2014 at 20:36 Comment(5)
Seems to be working for me (note the inordinately large size of A). Or were you hoping that the data ptr is pointing to would be over-aligned? That would require violation of causality.Fetlock
Maybe your compiler doesn't support an alignment of 64?Ary
Thanks Igor, that is showing the source of my misunderstanding. The pointer is aligned, not the data to which it points. I was hoping the data block would come out aligned.Lucie
Only starting with version 15 does ICC support alignment specifiers.Energetic
How can the implementation of new possibly know that the pointer it produces would eventually be assigned to a variable declared with alignas? That's what I mean by causality violation - you expect the implementation to be able to predict the future.Fetlock
K
6

Using the alignas(N) keyword on a member of a class causes this member to be aligned according to the specified alignment, not any entity potentially pointed to. After all, when initializing a pointer with a value there is no control to align the already existing objects.

You might want to have a look at std::align() which takes

  1. A specification for the alignment of the returned pointer.
  2. The size of the aligned block.
  3. A pointer to allocated memory.
  4. The amount of the allocated memory.

It returns a correspondingly aligned pointer unless there is not enough space to satisfy both the alignment and size requirements. If thereis not enought space the function return a null pointer.

Kaddish answered 17/12, 2014 at 20:57 Comment(4)
Replacing ptr = x; with ptr = decltype(ptr)(x &~ uintptr_t(64-1)); would guarantee that the ptr is aligned on 64 byte boundaries. Not in a good way, admittedly.Angy
@Yakk: I think using std::align() is preferable. What the implementation does to appropriately align the ponter is entirly up to the implementation. Since your approach is likely to interfere with the memory in front of the pointer you'd probably want to first offset the pointer a suitable amount.Plaided
I think the real problem with my "solution" is that I went off and modified a pointer willy nilly. The pointer is aligned, but it doesn't point to anything useful.Angy
Also note that alignof and std::align are only guaranteed to work for so-called fundamental alignment values, i.e., alignment values <= alignof(std::max_align_t), which often is 16. In the OP code, one should thus check the respective implementation for support of extended alignment values.Neogaea

© 2022 - 2024 — McMap. All rights reserved.