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

Nin*_*wil 8 c++ compiler-warnings visual-studio language-lawyer visual-studio-2015

我的代码中有以下行

signed int test_case= -2147483648;
Run Code Online (Sandbox Code Playgroud)

这会产生错误:

C4146一元减运算符应用于无符号类型,结果仍未签名

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

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

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

signed long test_case= -2147483648;
Run Code Online (Sandbox Code Playgroud)

以下更改编译正常:

signed int test_case= -2147483647;

signed int test_case= 2147483649;

signed long test_case= -214748364800;
Run Code Online (Sandbox Code Playgroud)
  • 有没有人用Visual Studio 2015编译器看到这个问题?
  • 它是如何定义数据类型的?
  • 如何检查范围?
  • 为什么它似乎忽略了"签名"任务?

谢谢

Bat*_*eba 9

这是编译器错误.

首先要注意的是:-2147483648 不是文字.在C++中没有负面文字这样的东西.

-2147483648是一个编译时可评估的常量表达式,由2147483648和一元减号运算符组成.

在针对Windows x64的MSVC上(其中int和long都是32位),2147483648 为a long long int,因此-2147483648也是如此.我的理解是标准坚持签名类型,除非你使用十六进制或八进制文字.

signed int在这种情况下,缩小转换是明确定义的,因为您的目标是具有32位2的补码int类型的平台.

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


Hum*_*awi 6

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


来自MSDN:

编号2147483648.因为它大于2147483647的最大整数值,所以2147483648的类型不是int,而是unsigned int.

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

解:

auto test_case= -2147483648ll;
Run Code Online (Sandbox Code Playgroud)