This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: std::vector move assign patch
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: libstdc++ at gcc dot gnu dot org
- Cc: Jonathan Wakely <jwakely dot gcc at gmail dot com>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 25 Apr 2017 13:52:53 +0100
- Subject: Re: std::vector move assign patch
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx04.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx04.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jwakely at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com EED3A8047D
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com EED3A8047D
- References: <52BDC6AD.5030207@gmail.com> <CAMe9rOok7WqKip7MAB885B_ZJonx5H3UpvUyZopiHur6W-tk2w@mail.gmail.com> <CAH6eHdSuwbuXzs0fmy4iJ6z+AUiFaKXNe1qhzzmNACnsdNKXhQ@mail.gmail.com> <alpine.DEB.2.20.1704220003540.2493@stedding.saclay.inria.fr>
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.