c++ - How to avoid strict aliasing errors when using aligned_storage -
i'm using std::aligned_storage backing storage variant template. problem is, once enable -o2 on gcc start getting warnings of 'dereferencing type-punned pointer break strict aliasing`.
the real template more complex (type checked @ runtime), minimal example generate warning is:
struct foo { std::aligned_storage<1024> data; // ... set() uses placement new, stores type information etc ... template <class t> t& get() { return reinterpret_cast<t&>(data); // warning: breaks strict aliasing rules } }; i'm pretty sure boost::variant doing same thing this, can't seem find how avoid issue.
my questions are:
- if using
aligned_storagein way violates strict-aliasing, how should using it? - is there strict-aliasing problem in
get()given there no other pointer based operations in function?- what if
get()inlined? - what
get() = 4; get() = 3.2? sequence reordered dueint,floatbeing different types?
- what if
std::aligned_storage part of <type_traits>; of rest of inhabitants of header file, holder typedefs , not meant used datatype. job take size , alignment, , make pod type characteristics.
you cannot use std::aligned_storage<len, align> directly. must use std::aligned_storage<len, align>::type, transformed type, "a pod type suitable for use uninitialized storage object size @ len , alignment divisor of align." (align defaults largest useful alignment greater or equal len.)
as c++ standard notes, type returned std::aligned_storage array (of specified size) of unsigned char alignment specifier. avoids "no strict aliasing" rule because character type may alias other type.
so might like:
template<typename t> using raw_memory = typename std::aligned_storage<sizeof(t), std::alignment_of<t>::value>::type; template<typename t> void* allocate() { return static_cast<void*>(new raw_memory<t>); } template<typename t, typename ...arg> t* maker(arg&&...arg) { return new(allocate<t>()) t(std::forward<arg>(arg)...); }
Comments
Post a Comment