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

Sebastian Redl sebastian.redl at getdesigned.at
Tue Sep 25 04:34:43 PDT 2012


On 25.09.2012 01:36, Ladislav Nevery wrote:
> ...The old state of city[1] may need to be
> cleaned up.  Thus, you would also have
> to call city[1].~Skyscapper(), first.
>
> I see this more like interesting new feature. The ability to recreate object
> just by reinvoking constructor with new parameters is welcome adition at
> least for me.
An "interesting new feature" is one thing, doing it behind the scenes as 
an optimization is completely different. (Not that I agree with this 
being interesting.)
> ...if SkyScrapper::SkyScrapper(const char *)
> throws, the state of city[1] is undefined.
>
> The behavior is already defined as part of c++ iso standard in "placement
> new" section.
> The moment user decided to invoke constructor he agreed to loose old object
> so I don't see problem there.
The user did no such thing. The user decided to create a temporary and 
then move-assign it to the old position. You want the compiler to decide 
for him that instead there will be a placement new without calling the 
destructor.
Which, by the way, is in no way defined by the C++ standard. 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.

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.
> ...There's no way to invoke the destructor
> /after/ calling SkyScrapper, since that
> would leave two objects at the same address
> while the constructor is running.
>
> yes there is exatly like in placement new case. since destructor handles
> only dynamic members not object itself that is statically preallocated and
> can't be deallocated alone.
The destructor is there to perform cleanup of any kind. Maybe unregister 
the object in some global map. You don't call the destructor, you've got 
a problem.
Placement new requires raw memory.
> The destructor situation is exactly the same as if some constructor throws
> during any static array creation.
No.
> Only dynamic memory members can be undefined.
That doesn't even mean anything.
>   And this situation is no
> different from todays implementation of static arrays so no different
> behavior there either.
Wrong.
> I think by using the same code that placement new generates behavior will be
> exactly as in c++ iso standard defines for placement new.
Yes, indeed. It will be just as undefined as if you placement new over 
an existing object.
If you want to do that, use placement new. Don't expect perfectly valid 
code to be transformed to invalid code.
> I wouldnt worry about =& copy or =&& move operator not being called in this
> case of array element creation since that was the whole purpose of the
> optimization.
An optimization is a code transformation that preserves behavior. The 
cases where we could prove that your transformation preserves behavior 
are those that are so trivial that inlining, value propagation and dead 
store elimination will have exactly the same effect anyway.
> That is creating in array as it should had been in c++ from the start.
> Instead of usual inefficient create temp and copy (&= ) or create temp and
> half copy(static mem) and half move(dynamic mem) in (=&&).
C++ has lifetime rules for objects. Those are there for a reason.
> Now using such optiomization switch will be more popular since  you just
> recompile any old code without any  change and get performance boost that
> you can't get by writing zillion of duplicite && operator variants since
> they solve only heap.
And as a side effect, you get subtle bugs. Yay!

Sebastian



More information about the cfe-dev mailing list