On 07/23/2014 07:29 AM, Richard Biener wrote:
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'.
Right, and I'm talking about the type of 'x', not the type of *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?
That's fine.
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'?
I think we'd prefer to only treat unsigned char specially, but plain
char is also allowed for historical reasons.
That said, as a matter of QOI I think only special-casing character
types would be a bad thing (see your hold_any example).
Well, there's a tradeoff between expressiveness and optimization. But
perhaps you have a better sense of that than I.
Jason