std::vector move assign patch

Jonathan Wakely jwakely@redhat.com
Tue Apr 25 12:52:00 GMT 2017


On 24/04/17 22:10 +0200, Marc Glisse wrote:
>It seems that this patch had 2 consequences that may or may not have 
>been planned. Consider this example (from PR64601)
>
>#include <vector>
>typedef std::vector<int> V;
>void f(V&v,V&w){ V(std::move(w)).swap(v); }
>void g(V&v,V&w){ v=std::move(w); }
>
>1) We generate shorter code for f than for g, probably since the fix 
>for PR59738. g ends up zeroing v, copying w to v, and finally zeroing 
>w, and for weird reasons (and because we swap the members one by one) 
>the standard prevents us from assuming that v and w do not overlap in 
>weird ways so we cannot optimize as much as one might expect.

f has an additional precondition (that the allocators of the vectors
being swapped must propagate on swap or be equal) and so the swap code
doesn't have to worry about non-equal allocators.

g has to be able to cope with the case where the allocator doesn't
propagate and isn't equal, and so is more complicated.

However, the propagation trait is known at compile-time, and for the
common case so is the equality condition, so it's unfortunate if that
can't be simplified (I'm sure you've analysed it carefully already
though!)


>2) g(v,v) seems to turn v into a nice empty vector,

Yes.

>while f(v,v) turns 
>it into an invalid vector pointing at released memory.

Does it?! I don't see that happening, and it's a bug if it does.

>Since 2) is a nice side-effect, it may not be worth rewriting 
>operator= in a way that improves 1) but loses 2). Anyway, just 
>mentioning this here.



More information about the Libstdc++ mailing list