Boost logo

Boost :

Subject: Re: [boost] [move][container] Review Request (new versions of Boost.Move and Boost.Container in sandbox and vault)
From: Thomas Klimpel (Thomas.Klimpel_at_[hidden])
Date: 2009-10-17 12:26:01


Howard Hinnant wrote:
> So why do it? What's the benefit even if the cost is small?
>
> Consider std::remove: This is one of the few algorithms in
> <algorithm> which is not a "resource preserving" permutation.
> Consider remove({a, b, c, d, e}, c). This will result in the sequence
> {a, b, d, e, e'}. To achieve this result, the following move
> assignments will take place:
>
> c = move(d);
> d = move(e);
>
> The first move assignment is not into a resource-less c. If move
> assignment into c doesn't "clear", when do those resources go away?
> For most resources (such as memory), it doesn't really matter when.
> The resources will still be owned if move-assignment doesn't
> aggressively destroy them (probably by e').
>
> But for some resources (threads, file handles, mutexes), it will
> matter if they live too long. The client calling std::remove may or
> may not destruct e' "soon". But the client asked std::remove to
> remove c (and presumably all of c's resources). I do not think it
> would be a good idea for std::remove to also say: Oh, and you better
> destruct e' too just to make sure c is really gone.

I was initially looking for an example of this sort to "prove" that "clear" is required, but came to realize that I probably won't find one. (The examples Dave gave me are sufficient to "prove" that "clear" is required, but they are related to subtleties of the C++ language and not inherent in moving itself.)

But why do I think that this example doesn't "prove" that "clear" is required? Consider "remove({a, b, c, d, c}, c)" instead of "remove({a, b, c, d, e}, c)". This will result in the sequence {a, b, d, d', c}. So the assumption that the client asked std::remove to remove c (and presumably all of c's resources) is simply not true. The client really has to destruct the elements of the tail range to ensure that c is really gone, even if the move-assignment operator calls "clear".

> This is the benefit of move assignment "clearing" potentially
> significant resources aggressively. I believe this benefit outweighs
> the cost.

My current understanding is that there are more subtle reasons why move assignment should "clear" potentially significant resources aggressively.

There is still the open point whether self-move-assignment should be forbidden. I wrote in another mail: "On the other hand, as long as the absence of conclusive counter examples can't be "proved", ruling that move-assignment may generally be implemented as swap will be risky or worse." I think the same should apply to self-move-assignment: As long as it can't be proved that forbidding self-move-assignment does no harm, ruling that self-move-assignment is forbidden will be risky or worse.

Regards,
Thomas


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk