为什么在比较 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) )
,则不会显示该警告。
- 这里发生了什么事? int从哪里来?
- 这真的会导致不正确的行为吗?
- 是否有更简洁的方法来使其静音? (或者写 uint16_t 文字的更简洁的方式?)
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
我有这样的代码:
#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) )
,则不会显示该警告。
- 这里发生了什么事? int从哪里来?
- 这真的会导致不正确的行为吗?
- 是否有更简洁的方法来使其静音? (或者写 uint16_t 文字的更简洁的方式?)
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
.