Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C Integral Overflow?

Tags:

c

c89

have a peek at this. The compiler is complaining that I have an integer overflow, but when I look at the C89 standard's rules for integral promotion along with the values in that expression, it seems to me that there is no overflow.

rutski@imac:~$ cat test.c 
#include <stdio.h>
#include <inttypes.h>

const uint32_t value =
    (0x7F-0x00 + 1) * (256 + 256*256 + 256*256*256) +
    (0xDF-0xC2 + 1) * (256 + 256*256 + 256*256*256);

int
main(void)
{
    printf("value = %"PRIu32"\n", value);
    return 0;
}
rutski@imac:~$ gcc -std=c89 -pedantic -Wall -Wextra test.c
test.c:5: warning: integer overflow in expression
test.c:6: warning: integer overflow in expression
test.c:6: warning: overflow in constant expression
rutski@imac:~$ ./a.out 
value = 2661195264
rutski@imac:~$ 

Moreover, google confirms that the answer of 2661195264 is the correct value for that expression! (See this link)

So, how is it that the program can produce a correct value when there was integer overflow? And more importantly, how is it that there was integer overflow in that expression to begin with?

like image 682
fieldtensor Avatar asked Jul 07 '11 19:07

fieldtensor


People also ask

Does C have integer overflow?

(Arithmetic) Integer Overflows An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold. The C standard defines this situation as undefined behavior (meaning that anything might happen).

What happens when an integer overflows in C?

Integer Overflow is a phenomenon that occurs when the integer data type cannot hold the actual value of a variable. Integer Overflow and Integer Underflow in C, do not raise any errors, but the program continues to execute (with the incorrect values) as if nothing has happened.

How do you fix arithmetic overflow in C?

There are two ways to get around this: Cast the numbers to a bigger integer type, then do the addition there, and check if the result is in the right range. Do the addition normally, then check the result (e.g. if (a+23<23) overflow).

Does C overflow?

In C programming language, a computation of unsigned integer values can never overflow, this means that UINT_MAX + 1 yields zero. More precise, according to the C standard unsigned integer operations do wrap around, the C Standard, 6.2.


2 Answers

(0x7F-0x00 + 1) * (256 + 256*256 + 256*256*256)

has the value 2155905024; the largest representable signed 32-bit int is 2147483647, so you have indeed produced an overflow. It happens to have given you the expected result anyway (you got lucky).

Note that your entire initializer has signed type (type int, specifically), as none of the literals are suffixed. The expression is evaluated as a signed int, then the resulting value is converted to an unsigned integer.

like image 83
Stephen Canon Avatar answered Oct 31 '22 21:10

Stephen Canon


Although your constants are all positive, they are still signed integers. You are overflowing the range of a signed integer. The result is converted to unsigned as the last step when it is assigned to the variable.

The bit patterns for addition, subtraction, and multiplication are identical between signed and unsigned operations. While the compiler is not required to provide the correct answer in this case, it's just the most natural result.

like image 45
Mark Ransom Avatar answered Oct 31 '22 21:10

Mark Ransom