When developing stack-based containers for RDESTL I’ve encountered the following problem - how to get block of uninitialized memory that’s aligned properly for type T. Consider fixed_vector class:

template class fixed_array { ... char m_data[N * sizeof (T)];

template struct alignof_helper { char x; T y; }; template struct alignof { enum { res = offsetof(alignof_helper, y) }; };

CHECK_EQUAL( 16 , rde :: alignof < __m128 >:: res);

First part of a problem solved. However, “res” cannot be simply used as an argument to __declspec(align). Instead, we have to create basic types with most common alignments.

__declspec (align( 16 )) struct aligned16 { uint64_t member[ 2 ]; }; template struct type_with_alignment { typedef char err_invalid_alignment[N > 0 ? - 1 : 1 ]; }; template <> struct type_with_alignment < 0 > {}; template <> struct type_with_alignment < 1 > { uint8_t member; }; template <> struct type_with_alignment < 2 > { uint16_t member; }; template <> struct type_with_alignment < 4 > { uint32_t member; }; template <> struct type_with_alignment < 8 > { uint64_t member; }; template <> struct type_with_alignment < 16 > { aligned16 member; }; ... template struct aligned_as { typedef typename internal :: type_with_alignment < alignof :: res > res; };

Finally, we create array of properly aligned types instead of chars. We also have to modify array size, as element size is no longer one byte, it needs to be corrected:

typedef typename aligned_as :: res etype_t; etype_t m_data[(N * sizeof (T)) / sizeof (etype_t)];

Reg 2009-03-08 11:26:37

I suppose you could use __alignof instead of this alignof_helper struct with offsetof.

admin 2009-03-08 11:59:45

jason gregory 2010-04-04 23:40:33