Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there a signedness issue when comparing uint16_t and unsigned int?

Tags:

c++

integer

I have a code like this :

#include <iostream>
using std::cout;
using std::endl;

int main() {
    uint16_t a = 0;
    uint16_t b = 0;

    if ( a - b < 3u )
    {
        cout << "cacahuète" << endl;
    }
    return 0;
}

When I compile it using g++ with -Wall, I get :

temp.cpp: In function ‘int main()’:
temp.cpp:9:13: warning: comparison of integer expressions of different signedness: ‘int’ and ‘unsigned int’ [-Wsign-compare]
    9 |  if ( a - b < 3u )
      |       ~~~~~~^~~~

That warning doesn't show up if I write if ( a - b < static_cast<uint16_t>(3u) ) instead.

  • So what's going on, here ? Where does the int come from?
  • Can this actually result in an incorrect behavior?
  • Is there a less verbose way to silence it? (or a less verbose way to write a uint16_t literal?)
like image 845
Eternal Avatar asked Oct 19 '25 03:10

Eternal


1 Answers

So what's going on, here ? Where does the int come from?

Integer promotion is going on here. On systems where std::uint16_t is smaller than int, it will be promoted to int when used as an operand (of most binary operations).

In a - b both operands are promoted to int and the result is int also. You compare this signed integer to 3u which is unsigned int. The signs differ, as the compiler warns you.

That warning doesn't show up if I write if ( a - b < static_cast<uint16_t>(3u) ) instead.

Here, the right hand operand is also promoted to int. Both sides of comparison are signed so there is no warning.

Can this actually result in an incorrect behavior?

if ( a - b < static_cast<uint16_t>(3u) ) does have different behaviour than a - b < static_cast<uint16_t>(3u). If one is correct, then presumably the other is incorrect.

Is there a less verbose way to silence it? (or a less verbose way to write a uint16_t literal?)

The correct solution depends on what behaviour you want to be correct.


P.S. You forgot to include the header that defines uint16_t.

like image 64
eerorika Avatar answered Oct 20 '25 18:10

eerorika



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!