Indexed array access should calculate string offset calculations based on index value and declared lower sizes. More on this a bit.
But first, your question is closely related to this simple observation:
void foo( char a[] ) { a[5] = 'a'; }
Why does the compiler let you do this? Because itβs C, and itβs absolutely your right to take your own foot off with undefined. Keeping this in mind:
void foo( char a[][5] ) { a[0][5] = 'a'; } // caller of foo() from somewhere char arr[4][5]; foo(arr);
It is as βvalidβ as the previous code (that is, you have the right to enter UB at your own risk). In this case, it will βworkβ, but only because the linear background of the base array is twenty elements wide, and we get only the sixth element, which is technically arr[1][0] .
The purpose of these lower dimensions is to correctly calculate access as follows:
void foo( char a[][5] ) { a[2][1] = 'b'; }
Superscript 2 must use the declared lower dimension (in this case 5 ) to efficiently calculate the linear displacement of the corresponding element. When aligning a 2D array in a 1D linear block, it is used for this:
char arr[20];
Pay attention to 5 . It should be known that the declared low dimension must correctly calculate the line jump (figure of speech).
Hope this makes it even a little clearer.
It should be noted that these compounds. Ie, the following:
char arr[3][4][5]; arr[1][2][3] = 'c';
effectively calculates the correct location against the linear background of the base array:
char arr[60];
And so on. Take it in as many sizes as you wish. All lower sizes must be known in order to do this correctly.