Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::sort - is passing a faulty comparator undefined behavior?

Consider this code:

std::sort(vec.begin(), vec.end(),
    [](const Foo& lhs, const Foo& rhs) { return !(lhs < rhs); }
);

If lhs == rhs, both lambda(lhs, rhs) and lambda(rhs, lhs) will return true, which violates the requirement to provide strict weak ordering. However, does the standard explicitly mark passing such a comparator as undefined behavior?

like image 759
user2478832 Avatar asked Jan 17 '16 01:01

user2478832


Video Answer


2 Answers

Warning: extreme language-lawyering follows.

The wording of the most recent draft of the standard puts it this way in [alg.sorting]p3:

For all algorithms that take Compare, there is a version that uses operator< instead. That is, comp(*i, *j) != false defaults to *i < *j != false. For algorithms other than those described in 25.4.3, comp shall induce a strict weak ordering on the values.

By using the word "shall", the standard is implicitly stating that violating it leads to undefined behavior.

Whether this requires that the given function impose a SWO for all possible values or just for the values given to the algorithm is not clear from the standard. However, since the restriction is stated in a paragraph that is talking about those specific algorithms, it's not unreasonable to assume that it is refering to the range of values provided to the algorithm.

Otherwise, the default operator< could not impose SWO for floats, thanks to NaN.

like image 147
Nicol Bolas Avatar answered Oct 20 '22 00:10

Nicol Bolas


[alg.sorting]/3 For algorithms other than those described in 25.4.3 to work correctly, comp has to induce a strict weak ordering on the values.

[alg.sorting]/4 The term strict refers to the requirement of an irreflexive relation (!comp(x, x) for all x) ...

Your comparison predicate is not a strict weak ordering.

like image 34
Igor Tandetnik Avatar answered Oct 20 '22 01:10

Igor Tandetnik