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_storage
in 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
,float
being 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