Arrays in C are quite "weak", and typically represented at run-time by just a pointer to the first element. When you declare something like int a[][], it's not possible to know how to compute the address of each element, since the type declaration doesn't say. This is why it won't compile, since the type is invalid.
If you could have int a[][], and then called it passing either int big[8][8] or int small[2][2], there's no way for the code inside the function to magically "adapt" for the proper address computation for these different arrays. This is why it won't work.
You can write a general function like int *matrix, size_t width and do the address computation manually, i.e. element "matrix[i][j]" is at matrix[i * width + j] for a row-major ordering.