I caught myself checking if the difference between two unsigned numbers was >= 0. I ran a test running Visual Studio 2022 Preview with the following code. In both cases the answer was true. That seems right to me as how could an unsigned number be considered negative?
However, when I changed all the types from UINT32 to UINT16 or UINT8, the first comparison returned false. I suppose it is related to the native size. But shouldn't the result be the same regardless of size? (UINT64 seems to behave like 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";
}
}
The issue arises because, when
aandbareUINT16orUINT8types, they have ranks less than that of theinttype, so, by the "usual arithmetic conversion" rules, they are promoted tointbefore thea - boperation is performed, and the result of that operation is also ofinttype.From this draft C++17 Standard (bolding for emphasis is mine):
However, on your platform, the
UINT32type has a rank that is the same as that ofint; so, in that case, no promotion is performed, and the result ofa - bis aUINT32(which cannot be negative).If you have the relevant feature enabled (it is by default, IIRC), then the Visual Studio IDE will actually tell you what the issue is, if you declare an
autolocal variable and initialize it witha - b. The following shows the popup displayed, when hovering over thedvariable, for the case when using theUINT32type:However, when we change the type to
UINT16, we see that thea - bexpression is, indeed, evaluated as anint: