As far as I understand, pointer arithmetic is defined mainly in expr.add. But it seems defined only for static arrays, not dynamic ones:
4 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 (9.3.3.4),76 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.
(4.3) — Otherwise, the behavior is undefined.
Basically it states that if you have a pointer to an object within an array, you can reach all other arrays elements (and define the location of one-past-last element) through pointer arithmetic. But regarding array definition, it links to dcl.array that seems to define only arrays declared through T arr[constant expression] this constant expression possibly empty.
I don't see arrays declared, for instance, with T* arr = ::new T[runtime unsigned integral expression].
Obviously pointer arithmetic is expected to behave in the same way for dynamic arrays but, out of pure curiosity, how is it defined in the standard?
T *arr = ::new T[whatever]does not declare an array. It defines [a definition is a type of declaration] a pointerarr, and initialises it with the result of anewexpression. Thatnewexpression dynamically allocates an array, and gives a result equal to the address of the first element of that dynamically allocated array. Point is - it is possible to allocate an array statically, dynamically, or (third possibility) automatically.T* arris no array. I points to one. And the type of that array isT[runtime unsigned integral expression]. Such an array is declared viaT arr[constant expression].