Our goal is to avoid bugs caused by strict aliasing in our networking libraries. My question is how to guarantee that we're not violating the aliasing rules while also getting the most optimization. I've read through a ton of information about this online and in some gcc discussions, but I don't see a consensus. Memcpy always works, but is dependent on optimization to avoid copies. The union of values is guaranteed to work by C++11, but may involve copies. In the past we've always used reinterpret_cast, but I don't believe that to be guaranteed by the standard. The __may_alias__ attribute is specific to gcc. Placement new changes the dynamic type of the memory which I believe guarantees correct access through a layout*. Two interesting gcc discussions: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=29286#c1 (placement new does not change the dynamic type as it should) https://gcc.gnu.org/ml/gcc-patches/2014-07/msg01440.html (Strenghten assumption about dynamic type changes (placement new)) https://gcc.gnu.org/gcc-4.4/porting_to.html (gcc 4.4 release notes) Each test works when built with -O3 on gcc-4.8.3, but I would like to standardize across compilers and versions. The optimization information generated by -fdump-tree-all is interesting here as it shows slightly different optimization for each case though reinterpret_cast and placement new generate identical code in the end. Here are tests illustrating the different options: #include <cstring> #include <memory> struct layout { int i; short s; char c; }; template<typename T, typename U> void verify(T t, U u) { if(t != u) abort(); } void mem_copy() { char storage[sizeof(layout)]; storage[0] = 1; storage[1] = 0; storage[2] = 0; storage[3] = 0; storage[4] = 2; storage[5] = 0; storage[6] = 3; storage[7] = 0; layout l; std::memcpy(&l, &storage, sizeof(layout)); verify(l.i, 1); verify(l.s, 2); verify(l.c, 3); } void union_copy() { union both { char storage[sizeof(layout)]; layout l; }; both b; b.storage[0] = 1; b.storage[1] = 0; b.storage[2] = 0; b.storage[3] = 0; b.storage[4] = 2; b.storage[5] = 0; b.storage[6] = 3; b.storage[7] = 0; verify(b.l.i, 1); verify(b.l.s, 2); verify(b.l.c, 3); } int placement_new() { char storage[sizeof(layout)]; storage[0] = 1; storage[1] = 0; storage[2] = 0; storage[3] = 0; storage[4] = 2; storage[5] = 0; storage[6] = 3; storage[7] = 0; auto l = new(storage) layout; verify(l->i, 1); verify(l->s, 2); verify(l->c, 3); } struct layout_alias: layout {} __attribute__((__may_alias__)); int may_alias() { char storage[sizeof(layout)]; storage[0] = 1; storage[1] = 0; storage[2] = 0; storage[3] = 0; storage[4] = 2; storage[5] = 0; storage[6] = 3; storage[7] = 0; auto l = reinterpret_cast<layout_alias*>(storage); verify(l->i, 1); verify(l->s, 2); verify(l->c, 3); } int reint_cast() { char storage[sizeof(layout)]; storage[0] = 1; storage[1] = 0; storage[2] = 0; storage[3] = 0; storage[4] = 2; storage[5] = 0; storage[6] = 3; storage[7] = 0; auto l = reinterpret_cast<layout*>(storage); verify(l->i, 1); verify(l->s, 2); verify(l->c, 3); } int main() { mem_copy(); union_copy(); placement_new(); may_alias(); reint_cast(); }