Одномерный доступ к многомерному массиву: хорошо ли определено поведение?

Я полагаю, что мы все согласны с тем, что считается идиоматическим C для доступа к истинному многомерному массиву путем разыменования (возможно смещенного) указателя на его первый элемент одномерным способом, например :

void clearBottomRightElement(int *array, int M, int N)
{
    array[M*N-1] = 0;  // Pretend the array is one-dimensional
}


int mtx[5][3];
...
clearBottomRightElement(&mtx[0][0], 5, 3);

Однако, языковой адвокат во мне нуждается в убеждении, что это на самом деле четко определенный C! Особенно

Имеет ли стандартную гарантию, что компилятор не будет вставлять промежуточные отступы, напримерmtx[0][2] а такжеmtx[1][0]?

Нормально, индексирование конца массива (кроме одного после конца) не определено (C99, 6.5.6 / 8). Таким образом, следующее явно не определено:

struct {
    int row[3];           // The object in question is an int[3]
    int other[10];
} foo;
int *p = &foo.row[7];     // ERROR: A crude attempt to get &foo.other[4];

По тому же правилу можно ожидать, что следующее будет неопределенным:

int mtx[5][3];
int (*row)[3] = &mtx[0];  // The object in question is still an int[3]
int *p = &(*row)[7];      // Why is this any better?

Так почему это должно быть определено?

int mtx[5][3];
int *p = &(&mtx[0][0])[7];

Так какая часть стандарта C явно разрешает это? (Давайте предположим, что C99 ради обсуждения.)

РЕДАКТИРОВАТ

Обратите внимание, что я не сомневаюсь, что это прекрасно работает во всех компиляторах. Я спрашиваю, разрешено ли это стандартом.

Ответы на вопрос(4)

Ваш ответ на вопрос