swap(v, v)は危ない?という話

-D_GLIBCXX_DEBUGを付けて以下のコードを実行するとアサートにひっかかります(https://stackoverflow.com/questions/13129031/on-implementing-stdswap-in-terms-of-move-assignment-and-move-constructor)。

struct S {
    vector<int> a;
}
S s;
swap(s, s);

どうやらswap内部でs = std::move(s)が発生し、これがヤバイっぽい(UBを引き起す?)です。 競技プログラミングにおいては、ランダムな並び換え(これはshuffle使えばいいけど)や、ガウスの掃き出し法などでswap(s, s)を使うことが多いと思います。

対策1

swap(s, s)をしないようにする。

対策2

UBと言ってもどうせ動くのでアサート自体を無効化する(https://stackoverflow.com/questions/22915325/avoiding-self-assignment-in-stdshuffle)

#include <debug/macros.h>
#undef __glibcxx_check_self_move_assign
#define __glibcxx_check_self_move_assign(x)

struct S {
    vector<int> a;
}
S s;
swap(s, s);