'Why comparison of 40 is less than or equal to -2147483648 true?

I am running the following code on my IDE using Visual Studio 2019:

cout << (40 <= -2147483648) << endl;

Both 40 and -2147483648 are in the range of signed int, so there should be no over- or underflow.

I expect that the output is false.

However, the output is true.

Why?



Solution 1:[1]

This is a non-standard feature (a.k.a "bug") of your compiler.

The C++ standard requires that decimal literals shall have one of these types:

  • int
  • long int
  • long long int

The compiler should use the first type that can represent the value in question.

Your compiler, however, uses an unsigned type, which contradicts the standard.

Fortunately this behaviour can be disabled by using /std:c++latest compiler option (which you should always use, unless you have a specific reason not to).

Note, the Microsoft compiler does not disable this non-standard behaviour with /std:c++14 and /std:c++17 switches, although the requirements for the literal types are the same in these versions of the standard. Only /std:c++20 or /std:c++latest switches are working.

If the non-standard behaviour is selected, and the warning level is set to /W2 or higher, the compiler will warn you about applying unary minus to an unsigned value. Always enable compiler warnings and treat them as errors.

Live demo

Edit: as noted in the comments, the actual compiler option that switches off the non-conformant behaviour is /permissive- (with the minus sign). It is implicitly set by /std:c++latest and /std:c++20 but not by other standard conformance options. For more information about the option, see the /permissive- documentation, though this particular document does not seem to mention this specific non-conforming behaviour. It is explained in C++ Conformance improvements instead.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1