One approach is to declare a flat 1D array and manually index into it:
Code: Select all
int *v; // At global scope
v = malloc(nrows * ncols * sizeof(int)); // In a function
v[row*ncols + col]; // Somewhere else
But that is annoying and error-prone. What I’m currently doing is declaring a pointer to an incomplete array type and casting it before use:
Code: Select all
int (*v)[]; // At global scope
v = malloc(nrows * sizeof(int[ncols])); // In a function
int (*x)[ncols] = v; // Somewhere else
x[row][col];
This is much clearer to use. It would be nice if I could declare it as
Code: Select all
int (*v)[ncols]; // At global scope
But that’s impossible because ncols does not have a value at the time of the declaration. However, the value of ncols never changes after it is set (it is a local variable in an Objective-C class, which is set on init and never changed), so it would be nice if I could make the cast “automatic”.
I could create a macro, or even a macro function, as:
Code: Select all
// At global scope
#define cast_v ((int(*)[ncols])v)
#define cast(A) ((int(*)[ncols])A)
// Somewhere else
cast_v[row][col];
cast(v)[row][col];
But those just seem hacky. Is there a better solution?