...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