Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ underflow and overflow

Tags:

c++

Hi I am new in here so please let me know if anything is wrong and I will try to better the next time .

I am trying to understand how underflow and overflow works in C++ .My understanding is if a variable's range is exceeded it will start from the other end of the range . Thus if minimum of short is -32768 and if we do a -1 to it the new value should be SHRT_MAX .(32767) Here is my code:

#include<iostream.h>
#include<limits.h>
#include<conio.h>
int main ( void )
{
 int testpositive =INT_MIN ;
 short testnegative = SHRT_MIN ; 
 cout<< SHRT_MIN<<"\n";
 cout << testnegative-1<<"\n";
 cout << INT_MIN << "\n";
 cout << testpositive-1 << "\n"; 
 cout<<testpositive-2;
 getch();
 return 0;
}   
like image 846
Knownow Avatar asked Apr 04 '12 12:04

Knownow


People also ask

What is underflow and overflow in C?

Integer Overflow occurs when we attempt to store a value greater than the data type's largest value. Similarly, Integer Underflow occurs when we attempt to store a value that is less than the least value of the data type.

What is the overflow and underflow?

Simply put, overflow and underflow happen when we assign a value that is out of range of the declared data type of the variable. If the (absolute) value is too big, we call it overflow, if the value is too small, we call it underflow.

What is overflow in C language?

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 is underflow with example?

Underflow can in part be regarded as negative overflow of the exponent of the floating point value. For example, if the exponent part can represent values from −128 to 127, then a result with a value less than −128 may cause underflow.


2 Answers

The exact behavior on overflow/underflow is only specified for unsigned types.

Unsigned integers shall obey the laws of arithmetic modulo 2^n where n is the number of bits in the value representation of that particular size of integer.

Source: Draft N3690 §3.9.1 sentence 4

This implies that unsigned arithmetic does not 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 unsigned integer type.

Source: Draft N3690 Note 47 for §3.9.1

For normal signed integer types instead the C++ standard simply says than anything can happen.

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined

Source: Draft N3690 §5 sentence 4

If we're talking about x86 processor (or most other modern processors) indeed the behavior is exactly what you describe and for the CPU there is no difference between a signed value or an unsigned value (there are signed and unsigned operations, but the value themselves are just bits).

Note that compilers can assume (and most modern optimizing compilers actually DO assume) that no signed integer overflow can occur in a correct program and for example in code like:

int do_something();
int do_something_else();

void foo() {
    int x = do_something();
    int y = x + 1;
    if (x < y) {
        do_something();
    } else {
        do_something_else();
    }
}

a compiler is free to skip the test and the else branch in the generated code completely because in a valid program a signed int x is always less than x+1 (as signed overflow cannot be considered valid behavior). If you replace int with unsigned int however the compiler must generate code for the test and for the else branch because for unsigned types it's possible that x > x+1.

For example clang compiles the code for foo to

foo():                                # @foo()
        push    rax
        call    do_something()
        pop     rax
        jmp     do_something()       # TAILCALL

where you can see that the ode just calls do_something twice (except for the strange handling of rax) and no mention of do_something_else is actually present. More or less the same code is generated by gcc.

like image 164
6502 Avatar answered Oct 17 '22 17:10

6502


Signed overflows are undefined behavior in C++.

For example:

INT_MIN - 1

-INT_MIN

are expressions that invoke undefined behavior.

SHRT_MIN - 1 and -SHRT_MIN are not undefined behavior in an environment with 16-bit short and 32-bit int because with integer promotions the operand is promoted to int first. In an environment with 16-bit short and int, these expressions are also undefined behavior.

like image 23
ouah Avatar answered Oct 17 '22 18:10

ouah