When I make the following calculation:
unsigned long long int data_size = 60123456 * 128 * sizeof(double); printf("data_size= %llu \n", data_size);
I surprisingly get overflow warning:
test.c:20:49: warning: overflow in expression; result is -894132224 with type 'int' [-Winteger-overflow] unsigned long long int data_size = 60123456 * 128 * sizeof(double); ^ 1 warning generated.
I cannot understand why this error appears even though I am using unsigned long long int
! Can someone explain why? Thank you
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
An integer overflow can cause the value to wrap and become negative, which violates the program's assumption and may lead to unexpected behavior (for example, 8-bit integer addition of 127 + 1 results in −128, a two's complement of 128).
Therefore, unsigned overflow results from any operation that crosses the divide between 2N-1 and 0. Stated more plainly, if performing addition (which should make the result larger) produces a smaller result, the addition caused unsigned overflow.
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).
Check for Integer Overflow. Write a “C” function, int addOvf (int* result, int a, int b) If there is no overflow, the function places the resultant = sum a+b in “result” and returns 0. Otherwise it returns -1.
An integer overflow or wraparound happens when an attempt is made to store a value that is too large for an integer type. The range of values that can be stored in an integer type is better represented as a circular number line that wraps around. The circular number line for a signed char can be represented as the following:
Because all operands in the constant expression are ints. Make one a long (5 * 60 * 1000L). Because it first does the math and then tries to assign it to the unsigned long. And because 5, 60 and 1000 all fit into an int the compiler will use it's default, an int. Try
Looking at the problem in reverse, if an attempt is made to store a number less than -128 in a signed char, the count wraps around to 127 and continues downwards, toward zero, from there. Thus, instead of what should be −129 the value 127 is stored, instead of −129 the value 126, and so on. This is sometimes called an integer underflow.
Overflow occurs before value is assigned to the variable. To avoid that use long long suffix:
60123456LL * 128 * sizeof(double)
(comments also suggest ULL which is not necessary here because values are within signed range, but that would be the generic way to go)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With