When should I care about possible offset overflow?

76 views Asked by At

When I need to define an offset in array, should I care about possible overflow of the offset value in case it has the same sizeof the index in the array?

Formally, signed value offset has twice less range than unsigned value index and setting offset larger than half of the index addressed range overflows the offset variable, but technically I can’t see situation when such overflow could lead to issues due to

C++ Standard 3.9.1.4 "Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer."

and

5.3.1.8 "The negative of an unsigned quantity is computed by subtracting its value from 2n, where n is the number of bits in the promoted operand."

I assume this is safe to use the same size unsigned type for index and signed type for offset.

The required operations:

  1. Add index and offset
  2. Get element by the resulting new index
  3. Compare two resulting indexes

No plans to compare two offsets which is a different story.

The code below confirms this, but maybe I am missing something and this could lead to some issues?

#include <iostream>

using index_t = unsigned int;
using offset_t = signed int;

int main()
{
    index_t index = 100;
    const offset_t extra_offset = 1000;

    offset_t offset_large = std::numeric_limits<offset_t>::max() + extra_offset; // Forlmally overflows the offset

    long long int output_convestion;

    index_t position_large = index + offset_large;
    output_convestion = position_large;

    long long int position = index;
    position += std::numeric_limits<offset_t>::max();
    position += extra_offset;

    std::cout << "Position large = " << output_convestion << "  should be = " << position <<
        (output_convestion == position ? " (equal) " : "(different)") << '\n';
}

Why do I care and don’t just use larger size offset? I want to save memory on large arrays of offsets and, at the end of the day, what type would you use offset for std::size_t while std::ptrdiff_t in most known implementations use the same size, but signed, formally answering to this question from existing code perspective.

0

There are 0 answers