variable length arrays are required in C99 and optional in C11, C17/18.
To detect, something like
#if defined(__STDC__) && defined(__STDC_VERSION__) && \
(__STDC_VERSION__ == 199901 || (__STDC_VERSION__ >= 201112 && __STDC_NO_VLA__ != 1))
#define VLA_OK 1
#else
#define VLA_OK 0
#ednif#endif
If code does not use a variable length arrays, code could take advantage that the address of the first element of the 2D array is equivalent to &arr[0][0]
and that 2D arrays are continuous.
void fill(void *arr, size_t rows, size_t cols, int val) {
int *a = arr;
for(size_t i = 0; i < rows; i++) {
for(size_t j = 0; j < cols; j++) {
*a++ = val;
}
}
}
Sample usage
#define IN 5
#define JN 3
int arr[IN][JN];
fill(arr, IN, JN, 0x45);
This does lose type checking.
Code instead could oblige passing the address of the first int
// v---v---- type checked
void fill(int *arr, size_t rows, size_t cols, int val) {
for(size_t i = 0; i < rows; i++) {
for(size_t j = 0; j < cols; j++) {
*arr++ = val;
}
}
}
Sample usage
#define IN 5
#define JN 3
int arr[IN][JN];
fill(&arr[0][0], IN, JN, 0x45);
// or
fill(arr[0], IN, JN, 0x45);