In C++, given a pointer (or iterator) a
and integer i
, which of these two expressions should you prefer to use: a + i
or &a[i]
?
These two expressions are equivalent and legal, as long as a + i
points to a valid element of the underlying array.
The a + i
expression has two advantages compared to &a[i]
:
It is legal and valid for a + i
to point to one element past the last element of the underlying array. In fact, this is how C++ iterators (or pointers) work with C++ iteration algorithms, their end()
value is one past the last element. It is illegal and undefined behavior for &a[i]
to be pointing to one past the last element. Checking tools might actually flag this as a violation, if they can deduce this statically.
When a
is a null pointer and i
is 0, a + i
is legal. The C++ standard specifically allows this to simplify generic programming code, so that it can operate without failing on all iterators and offset values. However, &a[0]
is illegal and fails if a
is a null pointer.
Both of the above subtle differences are listed in the C++20 standard §7.6.6 Additive operators:
When an expression J that has integral type is added to or subtracted from an expression P of pointer type, the result has the type of P. (4.1) — If P evaluates to a null pointer value and J evaluates to 0, the result is a null pointer value. (4.2) — Otherwise, if P points to an array element i of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) array element i + j of x if 0 ≤ i + j ≤ n and the expression P - J points to the (possibly-hypothetical) array element i − j of x if 0 ≤ i − j ≤ n.