在排序时更改排序顺序是否是未定义的行为

Is it undefined behaviour to change sort order while sorting?

本文关键字:排序 未定义 是否是 顺序      更新时间:2023-10-16

想象一下以下场景:

std::atomic<int>  values[10];
std::size_t      indices[10];
void sort() {
    std::iota(indices, indices+10, 0);
    std::sort(indices, indices+10,
        [&](size_t lhs, size_t rhs) { return values[lhs] < values[rhs]; });
}

在运行sort()时,另一个线程正在更改values。这是否只会导致索引之后没有正确排序,或者实际上是未定义的行为?

可能(见下文)这是未定义的行为; 在实践中,我见过普通的崩溃(对于容器外边界访问),即使只是对于不正确的(=不诱导总排序)比较器,并且在排序时更改索引的<肯定无法诱导总排序

有趣的是,该标准没有明确提到有关此问题的未定义行为;C++11 §5.4 ¶3 只是声明

要使 25.4.3 中描述的算法以外的算法正常工作,comp必须对值进行严格的弱排序。

而且我看不到"正常工作"的正式定义;甚至在整个第25章(描述<algorithm>)中也没有提到"未定义"这个词。

std::sort 需要一个满足严格弱排序规则的排序器。(在此回答中解释)

如果同时更改内容,则此排序可能无法保持,从而导致未定义的行为。(可能导致排序器中的无限循环,崩溃,之后索引未正确排序(如您所提到的),索引正确排序,2个月亮或其他东西)