4

std::sort is not guaranteed to be stable.

Is it guaranteed to be deterministic though?

For example, will this code always print 1?

struct S
{
    int a, b;
};

bool cmp(const S& lhs, const S& rhs)
{
    return lhs.a < rhs.a;
}

int main()
{
    std::vector<S> seq1 = {{1, 2}, {1, 3}};
    std::vector<S> seq2 = seq1;
    std::sort(seq1.begin(), seq1.end(), cmp);
    std::sort(seq2.begin(), seq2.end(), cmp);
    std::cout << (seq1.back().b == seq2.back().b) << '\n';
}

Also, is C++ standard library deterministic in general (apart from obviously indeterministic elements, like RNG and clocks)?

Phastasm
  • 894
  • 1
  • 7
  • 8
  • I don't believe the standard guarantees such determinism. To the best of my knowledge, it's silent on the issue, so the implementation is not required to be deterministic. – Igor Tandetnik Dec 25 '20 at 18:39
  • 1
    In fact, for the core language, it explicitly states the opposite (possibly in a non-normative note; I'm too lazy to look it up) - something to the effect that, in an expression like `f() + g()`, the order of the two function calls is unspecified, and moreover doesn't have to be the same between two evaluations of this expressions. – Igor Tandetnik Dec 25 '20 at 18:43
  • There is no such guarantee. Use [`stable_sort`](https://en.cppreference.com/w/cpp/algorithm/stable_sort) to be safe. – rustyx Dec 25 '20 at 19:08
  • One possible reason of instability is if thread is used under the ground. – Jarod42 Dec 25 '20 at 20:29

1 Answers1

3

The only requirement on a range once it has been sorted with std::sort is that the the elements are ordered according to the provided predicate. So if there are multiple valid orderings that are possible, then an implementation is conforming so long as it generates any one of them.

An implementation is allowed to generate different orderings each time std::sort is called on the same range. It can also generate a different ordering each time the program is executed.

Here are the requirements on std::sort. Note that there is no mention of any requirement that the resulting ranges be the same every time, so there is no guarantee that the results will be deterministic.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • Please link source and I will accept this answer. – Phastasm Dec 25 '20 at 19:11
  • @Phastasm I've linked to the standard page. There's no specific wording that says that it's "non-deterministic", but I think that can be inferred from the lack of a guarantee that it is "deterministic". – cigien Dec 25 '20 at 19:15
  • As well as the fact that there is stable_sort if more is required. – SoronelHaetir Dec 25 '20 at 19:18
  • @SoronelHaetir Stability and determinism are not the same and one could require just determinism like in the code from question. – Phastasm Dec 25 '20 at 19:21
  • @SoronelHaetir That doesn't actually prove that sort is non-deterministic. While it would be rather strange to guarantee determinism *without* stability, that would be possible, as Phastasm points out. – cigien Dec 25 '20 at 19:23