## DEV Community is a community of 714,858 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Posted on • Updated on

# Let's try C++20 | std::cmp_* functions

Today, I have discovered a very simple (but yet very efficient and useful) feature from C++20: the `std::cmp_*` functions. They allow to compare 2 integers, which can have different signedness, without getting bitten by implicit conversions.

Let's have look at this piece of code:

``````#include <iostream>

int main()
{
int a = -6;
unsigned int b = 3;

if (a < b) {
std::cout << "OK: a is lower than b\n";
} else {
std::cout << "Oopsi!\n";
}
}
``````

Yes, you've guessed right: it prints "Oopsi!".

Why?

Rule RSPEC-6214 from Sonar explains the issue very well:

Comparison between signed and unsigned integers is dangerous because it produces counterintuitive results outside of their common range of values.

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. For example, 2U < -1 is true.

C++20 introduced remedy to this common pitfall: a family of std::cmp_* functions defined in the header. These functions correctly handle negative numbers and lossy integer conversion. For example, std::cmp_less(2U, -1) is false.

This rule reports comparisons between signed and unsigned integers that involve negative numbers.

Let's try:

``````#include <iostream>
#include <utility>

int main()
{
int a = -6;
unsigned int b = 3;

if (std::cmp_less(a, b)) {
std::cout << "OK: a is lower than b\n";
} else {
std::cout << "Oopsi!\n";
}
}
``````

And now the code prints "OK: a is lower than b" 😁

Note that your compiler can emits warnings about conversions like this. With GCC, the option `-Wall` is enough:

``````<source>: In function 'int main()':
<source>:10:11: warning: comparison of integer expressions of different signedness: 'int' and 'unsigned int' [-Wsign-compare]
10 |     if (a == b) {
|         ~~^~~~
``````

The problem is the same in C but `-Wall` doesn't add `-Wsign-compare` for C, only in C+.

PS: my first article on dev.to was about funny integers conversions (but you must speak French to read it 😅)