Checking for underflow/overflow in C++?

17,419

Solution 1

To check for over/underflow in arithmetic check the result compared to the original values.

uint32 a,b;
//assign values
uint32 result = a + b;
if (result < a) {
    //Overflow
}

For your specific the check would be:

if (a > (c-b)) {
    //Underflow
}

Solution 2

I guess if I wanted to do that I would make a class that simulates the data type, and do it manually (which would be slow I would imagine)

class MyInt
{
     int val;
     MyInt(const int&nval){ val = nval;} // cast from int
     operator int(){return val;} // cast to int

    // then just overload ALL the operators... putting your check in
};

//typedef int sint32;
typedef MyInt sint32;

it can be more tricky than that, you might have to wind up using a define instead of a typedef...

I did a similar thing with pointers to check where memory was being written out side of bounds. very slow but did find where memory was being corrupted

Solution 3

Cert has a good reference for both signed integer overflow which is undefined behavior and unsigned wrapping which is not and they cover all the operators.

The document provides the following checking code for unsigned wrapping in subtraction using preconditions is as follows:

void func(unsigned int ui_a, unsigned int ui_b) {
  unsigned int udiff;
  if (ui_a < ui_b){
    /* Handle error */
  } else {
    udiff = ui_a - ui_b;
  }
  /* ... */
}

and with post-conditions:

void func(unsigned int ui_a, unsigned int ui_b) {
  unsigned int udiff = ui_a - ui_b;
  if (udiff > ui_a) {
    /* Handle error */
  }
  /* ... */
}

If you are gcc 5 you can use __builtin_sub_overflow:

__builtin_sub_overflow( ui_a, ui_b, &udiff ) 
Share:
17,419

Related videos on Youtube

Legend
Author by

Legend

Just a simple guy :)

Updated on April 15, 2022

Comments

  • Legend
    Legend about 2 years

    Is there a general way to check for an overflow or an underflow of a given data type (uint32, int etc.)?

    I am doing something like this:

    uint32 a,b,c;
    ... //initialize a,b,c
    if(b < c) {
       a -= (c - b)
    }
    

    When I print a after some iterations, it displays a large number like: 4294963846.

  • HostileFork says dont trust SE
    HostileFork says dont trust SE about 12 years
    There's a version of this called SafeInt that I learned about tonight. It's probably not a bad idea to use something like that most of the time, just not in performance critical code.
  • Faizan
    Faizan over 11 years
    is this the fact that in case of overflow the answer will always be a signed ( negative integer) ?
  • Stephen L
    Stephen L over 11 years
    Overflow of unsigned integers will never be signed, rather it will be a smaller unsigned integer than either of the original values.
  • Alexei Sholik
    Alexei Sholik almost 11 years
    Take care, signed overflow is undefined behavior in C.