[cfe-dev] Proposed C++ optimization with big speed gains with big objects

Cory Nelson phrosty at gmail.com
Tue Sep 25 07:42:47 PDT 2012


On Tue, Sep 25, 2012 at 7:57 AM, Ladislav Nevery <neuralll at gmail.com> wrote:
>>The user did no such thing. The user decided to create a temporary and
>>then move-assign it to the old position.
>
> No the user said let there be 1000 static objects
> and let first one be initialized with those parameters.
> The fact the nothing in code says how this goal is reached is good thing
> since it allows us to do it in efficient way.
>
>
>>You want the compiler to decide
>>for him that instead there will be a placement new without calling the
>>destructor.
>
> No I want this destructor be called and behave exactly like placement new
> part of standard. ie deleting only members.
>
>>Which, by the way, is in no way defined by the C++ standard.
>
> One optimization switch speeding all your old code without any change will
> be well worth it for many since it will produce faster and smaller code than
> zillion heap only && operators copy pasted everywhere.
>
>>You're
>>overwriting an object without properly ending its life. You're misusing
>>an object as raw memory.
>>You're invoking undefined behavior. End of story.
>
> No behavior and memory usage of basic object / members / destructors etc.
> is exactly as defined in standard for placement new. So whole behavior is
> exactly the same since copy of placement new code is used to implement it.
>
>>If you want to do that in your code, that's your business, and C++ won't
>>stop you from explicitly using placement new. Don't ask the compiler to
>>do it for you, because that is just insanely dangerous.
>
> I don's see the danger there any more than with placement new which is
> already part of clang and standard.
>
>>And as a side effect, you get subtle bugs. Yay!
>
> Can you make some example?

He already did. The problem is that your optimization changes what the
standard says will happen. Under normal circumstances,

Obj arr[10];
arr[0] = Obj();

Will be equiv to this:
Obj o;
arr[0] = move(o);

So if Obj's constructor fails, arr[0] is intact. Additionally,
operator= gets to handle any exception safety requirements. With your
optimization, this changes into

arr[0].~Obj();
new(&arr[0]) Obj()

So you see, exception safety can't be had anymore -- if the Obj()
constructor fails, you've got a destructed object and no way to
recover it.

-- 
Cory Nelson
http://int64.org



More information about the cfe-dev mailing list