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.