A more portable solution, common to C and C++, would be to use pointers to arrays.
For example:
unsigned int Array[5000];
unsigned int * Array_Offset_100 = &Array[0] - 100; // Initializing a pointer.
According to both language standards, pointers can be incremented or decremented by a scalar value as long as the result is not outside the range of a pointer. (E.g. Decrementing a pointer with value 0 (zero) is undefined behavior.)
Thus, a pointer to the first or beginning location of an array can be changed to point to before the array, within the array and past the array. The pointer variable does not contain any information about the size of the array that it is pointing to. So a pointer can have a value representing a location before the array.
Also, according to the language standard, the pointer can have a scalar offset added to it before it is dereferenced:
unsigned int value;
value = *(Array_Offset_100 + 100); // Add the offset to the pointer, **then** dereference.
Again, there is nothing in the standard about pointers knowing the size of the array it is pointing to (or the begin and end locations either).
Using array notation or square brackets, '[' and ']', results in an offset applied to the pointer before it is dereferenced, equivalent to the above example:
value = Array_Offset_100[100]; // Add offset, the value between '[' and ']', to pointer then dereference.
This is standard pointer arithmetic and dereferencing. Both operations are guaranteed by the standard and have no knowledge of the target array's dimensions and starting location. In fact, the pointer doesn't need to point to an array.
The validity of the dereference operation is left to the implementation (a.k.a. compiler) or the platform (OS or hardware). There are platforms that have valid data at address (location) 0x0. Many platforms will generate exceptions or signals when an attempt is made at deferencing to an invalid location (whether or not memory exists, or when the address is protected).
In summary, an array can be accessed with offsets or indices that are outside the declared range by using a pointer of the same type as an element of the array. Pointers carry no information about the range of elements it can point to. Pointers can be incremented and decremented as long as they don't go beyond the range of a pointer. The success of dereferencing a pointer ultimately depends on the platform. Compilers may add range checking to dereferencing operations.
(Please quote the sections of either C or C++ standard where pointers can't be incremented or decremented and restrictions about dereferencing when refuting this answer.)