Why does
int*[]
decay intoint**
but notint[][]
?
Because it would be impossible to do pointer arithmetic with it.
For example, int p[5][4]
means an array of (length-4 array of int
). There are no pointers involved, it’s simply a contiguous block of memory of size 5*4*sizeof(int)
. When you ask for a particular element, e.g. int a = p[i][j]
, the compiler is really doing this:
char *tmp = (char *)p // Work in units of bytes (char)
+ i * sizeof(int[4]) // Offset for outer dimension (int[4] is a type)
+ j * sizeof(int); // Offset for inner dimension
int a = *(int *)tmp; // Back to the contained type, and dereference
Obviously, it can only do this because it knows the size of the “inner” dimension(s). Casting to an int (*)[4]
retains this information; it’s a pointer to (length-4 array of int
). However, an int **
doesn’t; it’s merely a pointer to (pointer to int
).
For another take on this, see the following sections of the C FAQ:
- 6.18: My compiler complained when I passed a two-dimensional array to a function expecting a pointer to a pointer.
- 6.19: How do I write functions which accept two-dimensional arrays when the width is not known at compile time?
- 6.20: How can I use statically- and dynamically-allocated multidimensional arrays interchangeably when passing them to functions?
(This is all for C, but this behaviour is essentially unchanged in C++.)