Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aligning static array using std::aligned_storage

I'm trying to implement 16-byte alignment of simple static array using std::aligned_storage pattern:

#include <type_traits>
int main()
{
    const size_t SIZE = 8;
    using float_16 = std::aligned_storage<sizeof(float) * SIZE, 16>::type;
    float_16 mas;
    new(&mas) float[SIZE];//Placement new. Is this necessary? 

    mas[0]=1.f;//Compile error while attempting to set elements of aligned array
}

I get the following compile-error:

no match for «operator[]» in «mas[0]»

Then I tried to use explicit pointer casting:

float* mas_ = reinterpret_cast<float*>(mas); 

but this also yields compile-error:

invalid cast from type «float_16 {aka std::aligned_storage<32u, 16u>::type}» to type «float*»

Can anybody suggest me how align static array using std::aligned_storage correctly?

like image 873
gorill Avatar asked Sep 05 '13 13:09

gorill


Video Answer


2 Answers

You may use:

float* floats = new (&mas) float[SIZE];

and then you can use:

floats[0] = 1.f;

no reinterpret_cast at all :)

like image 72
Jarod42 Avatar answered Oct 08 '22 19:10

Jarod42


mas is not a pointer. reinterpret_cast must involve exclusively pointer, reference, or integral types, and only in some combinations: pointers to and from integral types, pointers to pointers, references to references, or an integral type to itself. In this case you are trying to case an std::aligned_storage<32u, 16u>::type to a pointer. The best you could get from this would be a reference to pointer cast, but that's not allowed†.

Try casting its address to another pointer type instead: reinterpret_cast<float*>(&mas);.


† for fun: the worst you could get would be if std::aligned_storage<32u, 16u>::type was a pointer type. It's doubtful, since 32-byte pointers are not common, but it could happen for std::aligned_storage<8u, 8u>::type, for example, in a very nasty standard library. Let's call it Hell++. So, in Hell++ it would compile fine, and you would end up casting the pointer type to another pointer type, and then doing all nasties on it like dereferencing it. This would be disastrous, because if std::aligned_storage<32u, 16u>::type was a pointer type, objects wouldn't have the address for the storage, but they would be the storage instead.

like image 23
R. Martinho Fernandes Avatar answered Oct 08 '22 18:10

R. Martinho Fernandes