C and C++ automatically coerce arrays to pointers. The error is caused due to the fact that this coercion happens only once (i.e. at only the first level). This means int [10]
will get coerced to int *
; but int [10][10]
can at most get coerced to an int *[10]
.
The reason has to do with memory layout. You see, a[i]
translates to *(a + sizeof(T) * i)
if a
is of the type T *
(assume adding to pointers directly adds without scaling); but if a
is of the type T [N]
, a[i]
translates to *(&a[0] + i)
. Thus, it follows that a value of type T [N]
can be coerced into a value of type T *
by taking the address of the first element -- the memory layouts are compatible in this case.
However, a two dimensional array a
(of type T [2] [4]
, say) will be stored differently than a double pointer (of type T **
). In the first case, you have the four elements,T [0][0]
to T [0][3]
laid out in memory followed by T [1][0]
to T [1][3]
and so on, modulo alignment. In the second case, you just have a bunch of pointers (to T
) laid out one after the other. In the first case, a[i][j]
will get lowered into *(&a[0][0] + sizeof(T) * 4 * i + sizeof(T) * j)
while in the second case it will get lowered into *(*(a + sizeof(T) * i) + sizeof(T) * j)
. The memory layouts are no longer compatible.