How to Prevent Integer Overflows in C++?

A simple solution that works fine in many situations.

Let’s consider the Sum function shown a few posts ago that exhibited bogus results due to signed integer overflow:

// Sum the 16-bit signed integers stored in the values vector
int16_t Sum(const std::vector<int16_t>& values)
{
    int16_t sum = 0;
 
    for (auto num : values)
    {
        sum += num;
    }
 
    return sum;
}

How can you fix the integer overflow problem and associated weird negative results discussed in the above blog post?

Well, one option would be to simply “step up” the integer type. In other words, instead of storing the sum into an int16_t variable, you could use a larger integer type, like int32_t or even int64_t. I mean, the maximum positive integer value that can be represented with a 64-bit (signed) integer is (2^63)-1 = 9,223,372,036,854,775,807: sounds pretty reasonable to represent the sum of some 16-bit samples, doesn’t it?

The updated code using int64_t for the cumulative sum can look like this:

// Sum the 16-bit signed integers stored in the values vector.
// The cumulative sum is stored in a 64-bit integer 
// to prevent integer overflow.
int64_t Sum(const std::vector<int16_t>& values)
{
    int64_t sum = 0;

    for (auto num : values)
    {
        sum += num;
    }

    return sum;
}

Considering the calling code of the initial blog post:

std::vector<int16_t> v{ 10, 1000, 2000, 32000 };
std::cout << Sum(v) << '\n';

this time with the int64_t fix you get the correct result of 35,010. Of course, also a simple shorter int32_t would have worked fine in this example. And, if you want to be super-safe, you can still wrap it in a convenient SafeInt<>.

Leave a comment