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.