On Wed, Jul 23, 2014 at 12:44 PM, Jason Merrill <ja...@redhat.com> wrote: > On 07/22/2014 02:34 PM, Richard Biener wrote: >> >> As discussed during the Cauldron keeping some builtin doesn't help because >> >> you are not forced to access the newly created object via the pointer >> returned >> by the placement new. That is, >> >> template <T> >> struct Storage { >> char x[sizeof(T)]; >> Storage() { new (x) T; } >> T& get() { return reinterpret_cast <T&> (x); } >> }; >> >> is valid > > > Yes. > > >> (and used in this way in Boost - with a type different from 'char' >> to force bigger alignment). > > > But I don't think that should be valid, unless the type contains a char > array at offset 0, as {std,boost}::aligned_storage; the C++ standard needs > improvement in this area.
Why especially at offset 0? I'm constructing in the place of 'x', not 'this'. Do you say that template <class T> struct Storage { T& get(i) { return new (x + sizeof (T) * i) T; } Storage (int n_) n (n_) {} int n; char x[sizeof (T)]; }; and doing Storage *s = new (malloc (sizeof (int) * 4)) Storage (4); s->get (2); isn't valid? > Looks like the small buffer optimization in boost::spirit::hold_any would > need to be tweaked, as it uses a void* to store anything the same size or > smaller, but that's the only dodgy case I see. I've seen other odd cases in GCC bugreports ultimately coming from Boost & friends (mpl or whatnot). Very likely older Boost versions of course. Btw, any reason why the standard treats 'char' and 'unsigned char' special but not 'signed char'? That said, as a matter of QOI I think only special-casing character types would be a bad thing (see your hold_any example). Richard. > Jason >