Visual Studio 2015 - 编译器警告(2 级)C4146

Visual Studio 2015 - Compiler Warning (level 2) C4146

我的代码中有以下行

signed int test_case= -2147483648;

产生错误:

C4146 unary minus operator applied to unsigned type, result still unsigned

但这仍然是有符号整数类型的数据范围:

__int32 signed, signed int, int –2,147,483,648 to 2,147,483,647

奇怪的是将它分配为 signed long 给出了同样的错误,即

signed long test_case= -2147483648;

以下修改编译成功:

signed int test_case= -2147483647;

signed int test_case= 2147483649;

signed long test_case= -214748364800;

谢谢

因为它是一个编译器错误,这个答案特定于 MSVC,它是来自 iso C++ 的错误看法。有关正确和标准的答案,请参阅@Bathsheba 答案。(我鼓励 OP 为未来的读者接受正确答案而不是这个答案)。


来自MSDN

The number 2147483648 is evaluated. Because it is greater than the maximum integer value of 2147483647, the type of 2147483648 is not int, but unsigned int.

换句话说,编译器会将-2147483648 处理为-2147483648 而不是-2147483648。所以 2147483648 部分被认为是 unsigned int 因为它大于 int。然后编译器应用导致此警告的 - 运算符。

解法:

auto test_case= -2147483648ll;

这是一个编译器错误。

首先要注意:-2147483648 不是 文字。 C++ 中没有否定文字这样的东西。

-2147483648 是由 2147483648 和一元减运算符组成的编译时可计算常量表达式。

在面向 Windows x64(其中 int 和 long 均为 32 位)的 MSVC 上,2147483648 应该long long int,因此也将如此-2147483648。我的理解是,标准坚持有符号类型除非你使用十六进制或八进制文字。

在这种情况下,向 signed int 的缩小转换是 well-defined,因为您的目标是具有 32 位 2 的补码 int 类型的平台。

进一步参考:参见http://en.cppreference.com/w/cpp/language/integer_literal