This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
PR 60519: Debug mode should check comparators for irreflexivity (Was: pdqsort - a faster std::sort)
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: François Dumont <frs dot dumont at gmail dot com>
- Cc: libstdc++ at gcc dot gnu dot org, Orson Peters <orsonpeters at gmail dot com>, Christopher Jefferson <chris at bubblescope dot net>
- Date: Sat, 11 Apr 2015 13:44:18 +0100
- Subject: PR 60519: Debug mode should check comparators for irreflexivity (Was: pdqsort - a faster std::sort)
- Authentication-results: sourceware.org; auth=none
- References: <CA+jCFLvDjSjPSF+dKDVuKWW-hsSK_LC3c=VwiFEhhx0EOyiqAA at mail dot gmail dot com> <CAJxLxMU_3vV1cozS1MnfSo5NNodW1J_1zZWuimdpCguO1cO-0w at mail dot gmail dot com> <CA+jCFLubcMg1OxspBjpcKjur6Vi6PJ=Ce_oSkA_b7OqcZR1UwQ at mail dot gmail dot com> <CAJxLxMX6CyVGxPgrZvvJ+Y62RN_86CQ8H0gFdUOHZde0UFJ2dA at mail dot gmail dot com> <CA+jCFLvUxRdmw71_H08ruDCf8QFmXcriE+G2_Cam4t5wQP-1gQ at mail dot gmail dot com> <CAJxLxMXfZ-GoTPO9uQ2Y9QyQJ_ep_+Ls4Di5q5A0B849Y32chg at mail dot gmail dot com> <CA+jCFLvtfsq6+0_r-iXAjE6JSBrxkDuaFu6FMguVhCghOdc0bw at mail dot gmail dot com> <CAJxLxMVhpu8rechANs8q+C4yxKA+587VCZsDqz0UiScMJBEXNA at mail dot gmail dot com> <alpine dot DEB dot 2 dot 11 dot 1504090019010 dot 1608 at laptop-mg dot saclay dot inria dot fr> <5528D498 dot 1040906 at gmail dot com>
On 11/04/15 10:00 +0200, FranÃois Dumont wrote:
Note that I also plan to implement PR 60519 thanks to those
wrapper as all algos are relying on it. It is a very nice central
place to implement additional checks.
Hmm, maybe I've misunderstood your suggestion, but that would mean
checking on every comparison in many cases. e.g. in std::sort we
have:
std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); â
Because this calls the single-argument version of __iter_comp_iter()
we can't just add the check in the constructor of _Iter_to_comp_iter
where we have a dereferencable iterator and the functor:
--- bits/predefined_ops.h.orig 2015-04-11 13:28:30.063009877 +0100
+++ bits/predefined_ops.h 2015-04-11 13:28:33.645013410 +0100
@@ -268,7 +268,13 @@
_Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1)
: _M_comp(__comp), _M_ref(*__it1)
- { }
+ {
+#ifdef _GLIBCXX_DEBUG
+ // Comparison must define a Strict Weak Ordering, like "less than",
+ // so must be irreflexive, i.e. x < x must be false.
+ __glibcxx_assert( !_M_cmp(_M_ref, _M_ref) );
+#endif
+ }
template<typename _Iterator2>
bool
That won't help std::sort, because it doesn't use _Iter_comp_to_iter.
If you add the irreflexivity check to _Iter_comp_iter then it needs to
check in operator(), on every call. That means we do 2N comparisons
instead of N, but we would get most of the benefit just by doing N+1
checks. (Alternatively _Iter_comp_iter could add a boolean member in
Debug Mode and only do the check once, but I really think this check
can be one of the "Debug Mode Lite" checks that doesn't affect ABI or
cause ODR violations and doesn't cost much in run-time performance.)
So I think we really want the irreflexivity check in std::sort itself,
so it can be done just once on entry to the function, not repeated at
every step. e.g.
#ifdef _GLIBCXX_DEBUG
// Comparison must define a Strict Weak Ordering, like "less than",
// so must be irreflexive, i.e. x < x must be false.
if (__first != __last)
__glibcxx_assert( !__comp(*__first, *__first));
#endif
std::__sort(__first, __last, __gnu_cxx::__ops::__iter_comp_iter(__comp)); â