int res = -2147483648 / -1;
cout << res << endl; // prints -2147483648
cout << -2147483648 / -1 << endl; // prints 2147483648
int res = numerator / denominator; // produces SIGFPE, Arithmetic exception interrupt
Note there're no negative integer literals.
There are no negative integer literals. Expressions such as -1 apply the unary minus operator to the value represented by the literal, which may involve implicit type conversions.
The literal 2147483648
is larger than the max value of int
, so its type will be long
(or long long
, depends on implementation). Then -2147483648
's type is long
, and the result of calculation (-2147483648 / -1
) is long
too.
For the 1st case, the result 2147483648
of type long
is implicitly converted to int
, but it's larger than the max value of int
, the result is implementation-defined. (It seems the result is wrapped around according to the rules of the representation (2's complement) here, so you get the result -2147483648
.)
For the 2nd case, the result with type long
is printed out directly, so you get the correct result.
For the 3rd case, you're doing the calculation on two int
s, and the result can't fit in the result type (i.e. int
), signed integer arithmetic operation overflow happened, the behavior is undefined. (Produces SIGFPE, Arithmetic exception interrupt here.)
negative integral constant converted to unsigned type
andunary minus operator applied to unsigned type, result still unsigned
on all-2147483648 / -1
lines – Wiring#define INT_MIN (-2147483647 - 1) // minimum (signed) int value
– Prochora2147483647
is DB,-2147483647
is still ok, and finally-2147483647 - 1
would still be DB as it would fit? Of course, in the program above overflow is unavoidable as(-2147483647 - 1) / -1
would still overflow and be UB. – ProchoraINT_MAX (-2147483648 - 1)
. Why is VC using what you quoted? What's the reason? – Ferbam2147483648
is UB even before the unary-
is considered. So the VC define gets around the problem by avoiding the2147483648
literal. – Prochoraunsigned int
, which isn't in the list so it seems wrong that Visual C++ will choose it. Also guaranteed to fit inlong long int
, which is why it is not UB. – Quinquereme2147483648;
is ok. And so isauto test{2147483648};
. I am surprised that VS will use an unsigned type, contrary to what is stipulated in the standard. Yet I found that it usesunsigned long
. I wonder why table 5 lists the unsigned types for binary, octal and hex, but not decimal literals? – Prochoraauto x = 0x0000000000000001;
automatically become whatever basic type meets theint64_least_t
idea – Quinquereme