Согласно пункту [expr.add], 7.6.6/4 стандарта языка C++, если у нас есть указатель p, который указывает на i-тый элемент некоторого массива из n элементов, и есть целочисленное значение j, то указатель p + j указывает на i + j-тый элемент в том случае, если 0 <= i + j <= n; в противном случае, поведение программы не определено.
Таким образом, поведение следующего кода не определено:
int arr[2];
int *pi = arr + 3; //UB
Однако, что произойдёт, если мы "выйдем за пределы" подмассива двумерного массива? Пример:
int arr[2][2];
int (*p)[2] = arr;
int *pi = *p;
pi = pi + 3; //UB?
Указатель p указывает на первый элемент массива arr, т.е. на массив из двух элементов типа int. Указатель pi указывает на первый элемент массива из двух элементов типа int. В выражении pi + 3 мы выходим за пределы массива из двух элементов типа int, хотя всё ещё находимся внутри массива arr.
Вопрос 1. Является ли выражение pi + 3 с точки зрения стандарта языка неопределённым поведением или нет?
Вопрос 2. Является ли корректным следующий код:
int arr2[1];
int *pi2 = arr2 + 1;
*pi2; //OK?
Меня интересует строка *pi2;.