On 4/5/2013 12:44 PM, Daniel Kr�gler wrote:
> On 2013-04-05 07:46, Balog Pal wrote:
>> To me that case is the same as copy-elision. For that the standard
>> grants a license to remove a cctor/dtor pair despite it can be
>> user-defined and can have observable behavior. The supposed
>> semantics suggest the actions shall cancel out properly.
>>
>> Is there a reason the same license to eliminate could not be
>> provided for op new/delete pair?
>
> How do you define such a new/delete pair?
Result of new passed to delete. How else? ;-)
> new/delete calls are
> completely independent and there exists no control by the core
> language for them. You can write code of the form ...
That's beside the point. If the implementation *can* figure out that a
result from new is passed to delete immediately, or between them only
irrelevant actions happen, is should be licenced to replace that with a
no-op. Cases where it can't or is too lazy to follow are not changed.
> Furthermore, we can call new in one function and delete on another.
Yep, and if the compiler can arrange to have all the code at some point
(maybe as late as linking or even execution), it can work with the info.
Like in the case of a local, if it's passed to a function by ref, but
the function is inlined and turns out the function does not touch that
variable, it can be eliminated entirely.
> This is different for implicitly called destructors, since we can
> always refer them to a corresponding construction in a local context
> and the compiler always knows about the relation of the "argument" of
> the destructor relative to the constructor.
I see only difference in chance to apply an optimisation in general --
and even that is diverging only for free-standing allocations, that are
pretty rare in many practices.
The main case for this scope is objects like string or vector, used as a
local. If I have an unused array<> it can be removed, but a similar
vector/string can not, because it has that mem-allocation inside. Even
better example is when you use unique_ptr or other smart pointers.
Our compilers do amazingly comprehensive data flow analysis for two
decades or more. Can unroll loops, chunk together operations, rearrange
by conditionals, just to name a few. It is common to create objects at
some distance from use, especially if conditions go between. With old
C++ it might be somewhat hosed in practice, but as constexpr gets
mainstream it will be even easier and more straightforward to optimize.
But operations involving new hoses that completely, as the involved
functions are volatile by nature -- and as mentioned can even be
replaced with unseen body. The effect is that we lose performance and/or
have to write more and messier code.