¿Cuál es el tipo de puntero de una matriz multidimensional cuando se pasa a una función?

Estoy aprendiendo C y punteros en mi clase de la universidad, y creo que tengo un buen conocimiento del concepto, excepto por la similitud entre matrices multidimensionales y punteros.

Pensé que dado que todas las matrices (incluso las multidimensionales) se almacenan en la memoria continua, se podría convertir de forma segura en un int* (suponiendo que la matriz dada es un int[] .) Sin embargo, mi profesor dijo que el número de estrellas en el La definición depende del número de dimensiones en la matriz. Entonces, un int[] se convertiría en un int* , un int[][] se convertiría en un int** , etc.

Así que escribí un pequeño progtwig para probar esto:

 void foo(int** ptr) { } void bar(int* ptr) { } int main() { int arr[3][4]; foo(arr); bar(arr); } 

Para mi sorpresa, el comstackdor emitió advertencias en ambas llamadas de función.

 main.c:22:9: warning: incompatible pointer types passing 'int [3][4]' to parameter of type 'int **' [-Wincompatible-pointer-types] foo(arr); ^~~ main.c:8:16: note: passing argument to parameter 'ptr' here void foo(int** ptr) ^ main.c:23:9: warning: incompatible pointer types passing 'int [3][4]' to parameter of type 'int *' [-Wincompatible-pointer-types] bar(arr); ^~~ main.c:13:15: note: passing argument to parameter 'ptr' here void bar(int* ptr) ^ 2 warnings generated. 

¿Que está pasando aqui? ¿Cómo podría cambiar las llamadas de función para que una de ellas acepte la matriz?

Edición: Este no es un duplicado de Cómo pasar una matriz multidimensional a una función en C y C ++ porque estoy preguntando cómo cambiar las llamadas de función, no las firmas de función.

Las matrices y los punteros no son completamente convertibles libremente. Para no recibir una advertencia, necesitarías una firma como void foo(int (*ptr)[4]) . Solo puede reemplazar el primer [] con un * al pasar una matriz como esa a una función.