uint8_t array[5][5];
void func(uint8_t *temp, uint8_t x, uint8_t y){.......}
func(array ,sizeof(array[0]) / sizeof(array[0][0]),sizeof(array) / sizeof(array[0]));
вызывает ошибку компилера RV:
main.c(28): error: #167: argument of type "char (*)[5]" is incompatible with parameter of type "char *"
вот и пошла фонтазия художника
Ну вот тут-то как раз &array[0][0] было бы полезным - чтобы на соответствие типов не ругался.void func(uint8_t *temp, uint8_t x, uint8_t y){.......}
func(array ,sizeof(array[0]) / sizeof(array[0][0]),sizeof(array) / sizeof(array[0]));
вызывает ошибку компилера RV:
main.c(28): error: #167: argument of type "char (*)[5]" is incompatible with parameter of type "char *"
вот и пошла фонтазия художника

Имя массива - это указатель на его первый (в смысле с нулевым индексом) элемент, но первым элементом для array будет array[0] - певый подмассив из 5 элементов в массиве array[5][5] (да, в языке С двумерных массивов [index,index] тоже "не очень есть", а есть массивы массивов).
А указывать как параметр первый подмассив array[0], чтобы передался адрес первого элемента этого подмассива...
Тут конфликта типов не будет, но это нечитаемо. Так что если имя массива не катит, то тогда - как и было изначально, &array[0][0].
По поводу func( int sy, int sx, int array[sy][sx]), введённом в С99 - может компилятору надо отдельно включить C99 каким-то ключиком? А то сюда ну просто очень просится.
Или он не умеет С99? Или умеет, но не весь? (а что тогда остаётся - //-комментарии да inline-функции? А, объявление переменных где угодно...).