2

I have a pointer which is defined as follows:

A ***b;

What does accessing it as follows do:

A** c = b[-1]

Is it an access violation because we are using a negative index to an array? Or is it a legal operation similar to *--b?


EDIT Note that negative array indexing has different support in C and C++. Hence, this is not a dupe.

Walter
  • 44,150
  • 20
  • 113
  • 196
ssn
  • 2,631
  • 4
  • 24
  • 28
  • 3
    See http://stackoverflow.com/questions/3473675/negative-array-indexes-in-c – Messa May 20 '14 at 22:28
  • 3
    Congratulations on becoming a three-star programmer. – chris May 20 '14 at 22:30
  • 1
    It's legal, but not pretty, and potentially undefined behavior until we see what you actually *initialize* `b` to. – Jeff May 20 '14 at 22:30
  • In C++, ordinary pointers (and therefore also arrays) are random access iterators. And random access iterators permit values to be accessed via the offset dereference operator (more commonly known as the subscript or `[]` operator). As others have pointed out, the negative index can be legal. Tricky code like this makes a good learning exercise, but try to avoid it in production code. – Dennis May 20 '14 at 22:40
  • @Dennis: Arrays are not iterators, and they're not pointers either (if that's what you were implying). – Benjamin Lindley May 20 '14 at 23:24

1 Answers1

9

X[Y] is identical to *(X + Y) as long as one of X and Y is of pointer type and the other has integral type. So b[-1] is the same as *(b - 1), which is an expression that may or may not be evaluated in a well-formed program – it all depends on the initial value of b! For example, the following is perfectly fine:

int q[24];
int * b = q + 13;

b[-1] = 9;
assert(q[12] == 9);

In general, it is your responsibility as a programmer to guarantee that pointers have permissible values when you perform operations with them. If you get it wrong, your program has undefined behaviour. For example:

int * c = q;   // q as above
c[-1] = 0;     // undefined behaviour!

Finally, just to reinforce the original statement, the following is fine, too:

std::cout << 2["Good morning"] << 4["Stack"] << 8["Overflow\n"];
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084