I was just reading some code and found that the person was using arr[-2]
to access the 2nd element before the arr
, like so:
|a|b|c|d|e|f|g|
^------------ arr[0]
^---------- arr[1]
^---------------- arr[-2]
Is that allowed?
I know that arr[x]
is the same as *(arr + x)
. So arr[-2]
is *(arr - 2)
, which seems OK. What do you think?
This is only valid if
arr
is a pointer that points to the second element in an array or a later element. Otherwise, it is not valid, because you would be accessing memory outside the bounds of the array. So, for example, this would be wrong:But this would be okay:
It is, however, unusual to use a negative subscript.
That is correct. From C99 §6.5.2.1/2:
There's no magic. It's a 1-1 equivalence. As always when dereferencing a pointer (*), you need to be sure it's pointing to a valid address.
I'm not sure how reliable this is, but I just read the following caveat about negative array indices on 64-bit systems (LP64 presumably): http://www.devx.com/tips/Tip/41349
The author seems to be saying that 32 bit int array indices with 64 bit addressing can result in bad address calculations unless the array index is explicitly promoted to 64 bits (e.g. via a ptrdiff_t cast). I have actually seen a bug of his nature with the PowerPC version of gcc 4.1.0, but I don't know if it's a compiler bug (i.e. should work according to C99 standard) or correct behaviour (i.e. index needs a cast to 64 bits for correct behaviour) ?
About why would someone want to use negative indexes, I have used them in two contexts:
Having a table of combinatorial numbers that tells you comb[1][-1] = 0; you can always check indexes before accessing the table, but this way the code looks cleaner and executes faster.
Putting a centinel at the beginning of a table. For instance, you want to use something like
but then you should also check that
i
is positive.Solution: make it so that
a[-1]
is-DBLE_MAX
, so thatx<a[-1]
will always be false.I know the question is answered, but I couldn't resist sharing this explanation.
I remember Principles of Compiler design, Let's assume a is an int array and size of int is 2, & Base address for a is 1000.
How
a[5]
will work ->This explanation is also the reason why negative indexes in arrays work in C.
i.e. if I access
a[-5]
it will give meIt will return me object at location 990. By this logic we can access negative indexes in Array in C.
What probably was that
arr
was pointing to the middle of the array, hence makingarr[-2]
pointing to something in the original array without going out of bounds.