Not getting Integer Overflow

244 Views Asked by At

Say I want to print some values. I am assuming that I should get Integer Overflow if my signed variable exceeds from TMin and TMax (in this case, using 4 byte int, 0x7FFFFFFF as Tmax and 0x80000000 as Tmin) but in these example I am not getting what I expect (explained in comments):

// Tmax = 0x7FFFFFFF == 2147483647 
// Tmin = 0x80000000 == -2147483648 
printf("1- overflow test: %d\n", 0x7FFFFFFF+1 ); // overflow - how compiler finds out it's a signed value, not an Unsigned one
printf("2- overflow test: %d\n", 0x80000000-1 ); // in contrast, why I am not getting an integer overflow here
printf("3- overflow test: %d\n", (int) 0x80000000-1 ); // overflow (Expected)
printf("4- overflow test: %d\n",(int) (0x7FFFFFFF+1)); // overflow (Expected)
4

There are 4 best solutions below

7
On BEST ANSWER

OP is not always experiencing signed integer overflow - which is undefined behavior.

The following is unsigned math as 0x80000000 is likely an unsigned integer. Hexadecimal constants are of the type that first fits them int, unsigned, long, unsigned long, ...

printf("2- overflow test: %d\n", 0x80000000-1 );

0x80000000-1 is an unsigned type as 0x80000000 first fits in an unsigned type, likely unsigned with the value of 2147483648u. 2147483648u - 1 --> 2147483647u.

0x7FFFFFFF+1 is a signed type as 0x7FFFFFFF first fits in a signed type, likely int with the value of INT_MAX.
int + int --> int and INT_MAX + 1 --> overflow.


OP said "0x80000000 as Tmin" is certainly a mis-understanding. In C, with 32-bit int/unsigned, 0x80000000 is a hexadecimal constant with the value of 2147483648. For OP, Tmin is more likely -INT_MAX - 1.

0
On

C is kind of inconsistent about numeric exceptions.

There are a few things you can do that almost always cause problems. If you divide by 0, your program will usually crash pretty hard, just as if you'd accessed an invalid pointer.

There are a few things you can do that are guaranteed not to cause a problem. If you say

unsigned int i = UINT_MAX;

and then add 1 to it, it's guaranteed to wrap around to 0.

And then there are a number of things where the behavior is undefined or unspecified. Signed integer overflow is one of these. Strictly speaking it's undefined (anything can happen, you can't depend on it). In practice, most computers quietly wrap around, just like for unsigned arithmetic.

Now, everything I've said has been about the run-time behavior of a program, but in this question's posted code fragment, all the arithmetic happens at compile time. Compile-time arithmetic operates mostly according to the same rules as run-time, but not always. Modern compilers tend to warn you about problematic compile-time arithmetic (my copy of gcc emits three warnings for the posted fragment), but not always.

9
On

First of all, let me tell you, (signed) integer overflow invokes undefined behavior.

In that scenario, anything can happen. You can neither trust nor reasonify the output of a code having UB.

Just to clarify, even

printf("2- overflow test: %d\n", 0x80000000-1 );

is UB. Though 0x80000000-1 is unsigned and not an overflow in itself, using %d will lead to a type mismatch which will technically lead to UB.

Regarding the Undefined behavior, from C11, annex §J.2,

Conversion to or from an integer type produces a value outside the range that can be represented.

7
On

Trying to invoke integer overflow is undefined behavior. As per standard, in that case anything, including outwardly appearing non-overflow can happen. What this outputs is uninteresting and irrelevant.

It may be that your compiler optimizes it out. It may be that your system refuses to be used in such a way, it may be that a sack of rice falling in china caused a butterfly effect that lead to this. Its anything but defined what happens there.

It may also be that your system decided that its integers are bigger. Only the lower limit of integer sizes (2 byte) is mandated in c (at least 4 is typical for standard computers). Your system could have 8 byte integers, or even bigger ones.