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

Ete*_*nal 4 c++ integer

我有这样的代码:

\n
#include <iostream>\nusing std::cout;\nusing std::endl;\n\nint main() {\n    uint16_t a = 0;\n    uint16_t b = 0;\n\n    if ( a - b < 3u )\n    {\n        cout << "cacahu\xc3\xa8te" << endl;\n    }\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
temp.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\ntemp.cpp:9:13: warning: comparison of integer expressions of different signedness: \xe2\x80\x98int\xe2\x80\x99 and \xe2\x80\x98unsigned int\xe2\x80\x99 [-Wsign-compare]\n    9 |  if ( a - b < 3u )\n      |       ~~~~~~^~~~\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
    \n
  • 那么这里发生了什么事?int 从哪里来?
  • \n
  • 这实际上会导致不正确的行为吗?
  • \n
  • 有没有更简单的方法来使其静音?(或者编写 uint16_t 文字的更简洁的方法?)
  • \n
\n

eer*_*ika 5

那么这里发生了什么事?int 从哪里来?

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

两个操作数都a - b提升为int,结果int也是。您将此有符号整数与3uis进行比较unsigned int。正如编译器警告您的那样,符号不同。

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

这里,右手操作数也被提升为int。比较双方均已签名,因此不会出现警告。

这实际上会导致不正确的行为吗?

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

有没有更简单的方法来使其静音?(或者编写 uint16_t 文字的更简洁的方法?)

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


PS 您忘记包含定义的标头uint16_t