为什么在比较 uint16_t 和 unsigned int 时会出现符号问题?

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

我有这样的代码:

#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;
}

当我使用带有 -Wall 的 g++ 编译它时,我得到:

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 )
      |       ~~~~~~^~~~

如果我改写 if ( a - b < static_cast<uint16_t>(3u) ),则不会显示该警告。

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

这里正在进行整数提升。在 std::uint16_t 小于 int 的系统上,当用作操作数(大多数二进制操作)时,它将被提升为 int

a - b中,两个操作数都被提升为int,结果也是int。您将此有符号整数压缩为 3u,即 unsigned int。正如编译器警告您的那样,符号不同。

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

这里,右边的操作数也提升为int。比较的两边都有签名,所以没有警告。

Can this actually result in an incorrect behavior?

if ( a - b < static_cast<uint16_t>(3u) ) 确实与 a - b < static_cast<uint16_t>(3u) 有不同的行为。如果一个是正确的,那么可以推测另一个是不正确的。

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

正确的解决方案取决于您想要正确的行为。


P.S。您忘记包含定义 uint16_t.

的 header