On Tue, Jul 22, 2014 at 3:54 PM, Jan Hubicka <hubi...@ucw.cz> wrote:
>>
>> As discussen 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); }
>> };
>
> This indeed looks like sensible use of placement new...
>>
>> is valid (and used in this way in Boost - with a type different from 'char'
>> to force bigger alignment).
>
> This testcase with char replaced to long or other POD type is still fine for 
> my analysis.
> I would like to assume that once a polymorphic type is built at a given 
> location, it can
> not be changed to other, that is:
>
>   template <T>
>  struct Storage {
>      Q x;
>     Storage() { new (x) T; }
>     T& get() { return reinterpret_cast <T&> (x); }
> };
>
> Where both T and Q are polymorphic types. I think essentially aliasing rules
> disallows this (for Q and T being different types at least, not sure if one
> inherits other) because Q gets constructed and thus accessed. But it is 
> sliperly
> indeed, as whole concept of placement new.
>
> I believe easiest way to go forward is to extend polymorphic_call_context to
> also hold speculative information about outer type.  In the cases I can detect
> a dynamic type but can not prove it did not changed, I still can use the
> speculative path.  This is not perfect, but will improve code quality.
>
> I am still hoping we can get sensible rules for placement new :)

I don't see why

long x[1024];

Q *q = new (x) Q;
q->~Q ();
new (x) T;

would be invalid.  I also don't see why

Q q;
q.~Q ();
new (&q) T;

would be.  Object lifetime is precisely specified and I don't see where it is
tied to (static) storage lifetime.

Richard.

> Honza

Reply via email to