https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70526
--- Comment #26 from rguenther at suse dot de <rguenther at suse dot de> --- On Tue, 3 May 2016, redi at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70526 > > --- Comment #25 from Jonathan Wakely <redi at gcc dot gnu.org> --- > std::aligned_storage has no equivalent of the addr() member function that > would > need adjusting, it's just the union U part of the AlignedStorage2 type in > comment 23, where sizeof(T) is a template parameter, rather than T. > > __gnu_cxx::__aligned_buffer<T> and __gnu_cxx::__aligned_membuf<T> are similar > to the class template discussed above, but if I understand the issue > correctly, > they don't need adjusting because we don't misuse them. > > We create objects in them with placement new, and we don't attempt to use the > aggregate copy (because that would obviously do the wrong thing). In fact I > don't think we ever try to copy those objects. The closest we get to copying > them would do something like: > > void f(__gnu_cxx::__aligned_buffer<X> buf) > { > __gnu_cxx::__aligned_buffer<X> buf2; > X* x = ::new (buf2.addr()) X(*buf.ptr()); > // use x > x->~X(); > } > > i.e. we create copies of the stored object using placement new, but don't copy > the aligned buffer objects themselves. > > > (In reply to Richard Biener from comment #20) > > (In reply to Jan de Mooij from comment #17) > > > So IIUC it's wrong to store to |typed| in the constructor, by doing this: > > > > > > *typed.addr() = reg; > > > > > > Why is that? Any suggestions on how to fix this on our end? > > > > No, it's valid to do that. > > It's only valid because Register is a trivial type. Otherwise you'd be > assigning to an object which was never constructed, i.e. it's lifetime never > started. > > In the general case the safe way to construct that object is with placement > new: > > ::new ((void*)typed.addr()) Register(reg); > > This begins the lifetime of a Register object at the desired location. std::aligned_storage<T> has the requirement of a POD type T. So I wondered about whether the intent was to make copying it by plain assignment possible. Using std::memcpy() on the object would always work at least as that is documented for POD types.