https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70530
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |SUSPENDED Last reconfirmed| |2016-04-04 Summary|You should probably add |[DR2468] You should |addressof (a) != addressof |probably add addressof (a) |(b) check to std::swap |!= addressof (b) check to | |std::swap Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Askar Safin from comment #0) > C++ standard says standard library functions may assume rvalue reference > arguments are unique, i. e. are not aliased to any other arguments (final > draft C++14 N3690 17.6.4.9). I think this implies that move assignment for > standard classes assume there will be no move assignment to itself. Also, I > think this is good idea for other classes to assume the same. That rule is actually defective, see: http://cplusplus.github.io/LWG/lwg-active.html#2468 > As well as I know there is no any mention in the standard that std::swap > argument should not point to the same object. So, code "swap (a, a)" is > legit. Moreover, this code can appear in real programs. For example, this is > code from http://en.cppreference.com/w/cpp/algorithm/iter_swap (as on > 2016-04-02): > > // libstdc++'s general std::iter_swap just calls std::swap in c++11 mode > template<class ForwardIt> > void selection_sort(ForwardIt begin, ForwardIt end) > { > for (ForwardIt i = begin; i != end; ++i) > std::iter_swap(i, std::min_element(i, end)); > } > > Current libstdc++ implementation of std::swap calls move constructor (ctor) > one time and move assignment (op=) two times. If we call std::swap (a, a), > then there will be move op= to itself. > > So, I think std::move should check whatever its arguments point to the same > object. That would not be conforming. > It seems all standard classes will work correctly currently if we call > std::swap (a, a) in stdlibc++. I. e. I cannot think about some concrete > libstdc++ class where std::swap (a, a) will cause any damage. But still > assuming rvalue reference is unique is good idea for other libraries, too. > And this is possible that some library author will assume this and std::swap > (a, a) will fail. > > So, what to do? My proposed solution is to fix std::swap. But there are > other variants, of course. For example, remove rvalue ref uniqueness > assumption from the standard. Or add requirement for code which calls > std::swap. Even if you decide to fix std::swap, I think it still be good > idea to modify the standard. For example, to stay explicitly that a = > std::move (a) is not allowed for standard classes, that this is recommended > for other class to assume there will be no code "a = std::move (a)", that > swap (a, a) is allowed and for this reason current libstdc++'s swap > implementation is not allowed The more likely direction is to require self-move (and therefore self-swap) to be valid for all standard classes.