Il y a un peu de confusion ici :
tout d'abord, la taille est connue puisque passée en second argument (ou alors si vous parlez du 2e niveau : elle est connue car on sait que ce sont des int : sizeof(int)).
Deuxièmement, il ne faut en effet pas confondre le cas le plus général int** et le cas particulier du passage à une fonction d'un tableau d'int à deux dimensions : int[M][N]. Mais attention ici on ne parlait pas d'un tableau d'int à 2 dimensions, mais bien d'un tableau de pointeurs sur des int.
J'essaye d'être plus clair (voir aussi le dessin en fin de message) :
il faut se rappeler que passer un tableau à une fonction se fait TOUJOURS comme un pointeur : quelque soit le type X (et Y, mais il n'importe pas ici), la fonction
est TOUJOURS exactement comme
[et c'est pour cela qu'il faut toujours avoir la taille du tableau comme paramètre supplémentaire]
donc la réponse à la question initialement posée est : oui :
est EXACTEMENT la même chose que
[Note : attention à ne pas oublier d'avoir la taille comme 2e paramètre).
Voici [cf image ci-dessous] l'illustration pour le code C suivant pour un type X quelconque :
...
X t[N] = { .... };
f(t);
Si vous appliquez ça à X étant « int* » vous voyez bien que vous avez le cas dessiné en bas à droite.