I have the following line in my code
signed int test_case= -2147483648;
which generates the error:
C4146 unary minus operator applied to unsigned type, result still unsigned
but this is still with the data range of teh signed integer type:
__int32 signed, signed int, int –2,147,483,648 to 2,147,483,647
The strange things is assigning it as signed long gives this same error, i.e.
signed long test_case= -2147483648;
The changes below compile OK:
signed int test_case= -2147483647;
signed int test_case= 2147483649;
signed long test_case= -214748364800;
- Has anyone seen this issue with Visual Studio 2015 compiler?
- How is it defining the data types?
- How is the range checked?
- Why does it seem to ignore the "signed" assignment?
Thanks
Since it is a compiler bug, this answer is specific to MSVC and it is wrong from iso C++ perspective. For the correct and standard answer please see @Bathsheba answer. (I encourage the OP to accept the correct answer instead of this answer for future readers).
From 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.
In other words, the compiler will deal with -2147483648 as -
and 2147483648
not as -2147483648
. So the 2147483648
part is considered as unsigned int
since it is bigger than int
. and then the compiler applies the -
operator which is leading to this warning.
Solution:
auto test_case= -2147483648ll;
This is a compiler bug.
First thing to note: -2147483648 is not a literal. There is no such thing as a negative literal in C++.
-2147483648 is a compile time evaluable constant expression consisting of 2147483648 and the unary minus operator.
On MSVC targeting Windows x64 (where an int and long are both 32 bit), 2147483648 should be a long long int
, and therefore so will -2147483648. My understanding is that the standard insists on a signed type unless you use a hexadecimal or octal literal.
The narrowing conversion to signed int
is, in this case, well-defined since you're targeting a platform with a 32 bit 2's complement int
type.
Further reference: see http://en.cppreference.com/w/cpp/language/integer_literal