Comparisons between signed and unsigned integers are dangerous because they produce counterintuitive results outside
their shared value range.
When a signed integer is compared to an unsigned one, the former might be converted to unsigned. The conversion preserves the two’s-complement bit
pattern of the signed value that often corresponds to a large unsigned result. The expression 2U < -1 evaluates to true,
for instance.
C++20 introduced a remedy to this common pitfall: a family of std::cmp_* functions defined in the <utility>
header:
-
std::cmp_equal
-
std::cmp_not_equal
-
std::cmp_less
-
std::cmp_greater
-
std::cmp_less_equal
-
std::cmp_greater_equal
These functions correctly handle negative numbers and are safe against lossy integer conversion. For example, the comparison of 2U and
-1 using std::cmp_less(2U, -1) evaluates to false and matches common intuition.