This must be a repeat question, but I have not found it after searching for 2 days ...
I'm using MSVC with /std:c17 /std:c 17 and trying to get alignas(64) to work with arrays of doubles. The syntax in the code below is the only one I have found that compiles, but it's not aligning ... typically, the array is unaligned about 75% of the time. I know there are many ways to do this with more complicated syntax, but isn't there a way that "just works" with alignas(), as it would for a structure or class?
double* AR;
int count=0, asize=10;
for (int i = 0; i < 1000; i )
{
AR = new double alignas(64)[asize];
if (((uintptr_t)AR & 63) != 0) count ;
//if (((uintptr_t)AR % 64) != 0) count ;
delete[] AR;
}
CodePudding user response:
While C 17 does have the means for operator new
to be given an alignment for the memory it allocates, there is no mechanism in C to specify the alignment for memory allocated by a new
expression outside of the alignment of the type being allocated. That is, if you perform a new T
or new T[]
, the alignment of the allocated pointer will be alignof(T)
. C 17 added alignment-based operator new
allocators, which allows them to support over-aligned types.
This is fine if you have control over T
and can specify its alignment at definition time via alignas
. But if you're using someone else's type or a fundamental type like double
, you can't change the alignment of those types. So there's no way to directly use a new
expression to allocate such memory.
You will have to use ::operator new
directly to allocate sufficient memory at the desired alignment, and then use placement-new
to actually create the objects there. Of course, placement-new
on arrays has a number of issues.
I suspect this compiles only because alignas
is considered an attribute and it is grammatically legal to shove an attribute before the []
in a new
expression. It isn't intended to actually work, as there is no statement in the section on new
expressions that allows it to get the alignment of the allocation from anything other than alignof(T)
.