Visual Studio C++对UINT16和UINT32的比较结果不同

Visual Studio C++ has different comparison results for UINT16 and UINT32

我发现自己正在检查两个无符号数之间的差异是否 >= 0。我 运行 使用以下代码测试 运行 Visual Studio 2022 预览版。在这两种情况下,答案都是正确的。这对我来说似乎是正确的,因为一个无符号数怎么会被认为是负数?

但是,当我将所有类型从 UINT32 更改为 UINT16UINT8 时,第一个比较返回 false。我想这与原始大小有关。但是无论大小,结果不应该是一样的吗? (UINT64 似乎表现得像 UINT32。)

#include <Windows.h>
#include <iostream>
using namespace std;

int main()
{
  UINT32 a = 5;
  UINT32 b = 10;
  UINT32 c = 0;

  if ((a - b) > 0)
  {
    cout << "\nTrue.";
  }
  else
  {
    cout << "\nFalse";
  }

  c = a - b;

  if ((c) > 0)
  {
    cout << "\nTrue.";
  }
  else
  {
    cout << "\nFalse";
  }
}

问题的出现是因为,当abUINT16UINT8类型时,它们比[=]少 14=]类型,所以,按照“通常的算术转换”规则,在执行a - b操作之前,它们被提升为int,并且该操作的结果也是int类型。

来自 this draft C++17 Standard(粗体表示强调是我的):

7.6 Integral promotions     [conv.prom]

1    A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (6.7.4) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

但是,在您的平台上,UINT32 类型的排名与 int 相同;因此,在这种情况下,不会执行任何提升,a - b 的结果是 UINT32(不能为负数)。


如果您启用了相关功能(默认情况下,IIRC),那么 Visual Studio IDE 实际上会告诉您问题所在,如果您声明 auto 局部变量并用 a - b 初始化它。下面显示了当鼠标悬停在 d 变量上时显示的弹出窗口,对于使用 UINT32 类型的情况:

然而,当我们将类型更改为 UINT16 时,我们看到 a - b 表达式确实被评估为 int: