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?

Columbo
  • 60,038
  • 8
  • 155
  • 203
user1683586
  • 373
  • 2
  • 12
  • 5
    Seems to be [working for me](http://rextester.com/LCVUW98273) (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. – Igor Tandetnik Dec 17 '14 at 20:41
  • Maybe your compiler doesn't support an alignment of 64? – Brian Bi Dec 17 '14 at 20:43
  • 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. – user1683586 Dec 17 '14 at 20:47
  • 1
    [Only starting with version 15 does ICC support alignment specifiers](https://software.intel.com/en-us/articles/c0x-features-supported-by-intel-c-compiler). – Columbo Dec 17 '14 at 20:55
  • 4
    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. – Igor Tandetnik Dec 17 '14 at 20:56

1 Answers1

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.

user703016
  • 37,307
  • 8
  • 87
  • 112
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • 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. – Yakk - Adam Nevraumont Dec 17 '14 at 21:16
  • @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. – Dietmar Kühl Dec 17 '14 at 21:23
  • 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. – Yakk - Adam Nevraumont Dec 17 '14 at 21:33
  • 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. – levzettelin Dec 17 '14 at 21:58