If I have a multidimensional array like this:
int arr2d[2][3] = {{0,1,2}, {10,11,12}};
I can pass it to a function like this:
void foobar(int arg[][3])
This is not a call by value, this is call by reference, so just an pointer to the start address, but the compiler still knows it is a 2D array and I'm able to access it like one in the function.
Now how does the same work in a struct?
typedef struct {
int arr2d[][3];
} Foobar_t
First this gives me: error: flexible array member in otherwise empty struct. I can fix this by doing so:
typedef struct {
int dummy;
int arr2d[][3];
} Foobar_t
It will compile without errors or warnings. But when I try to use it like Foobar_t foobar = {1337, arr2d} I get some warnings:
missing braces around initializer
initialization makes integer from pointer without a cast
And when accessing it: subscripted value is neither array nor pointer nor vector.
One dimensional arrays can easily be treated as pointers. But for multi dimensional arrays the compiler needs to know the size of the different dimensions to calculate the offsets correctly. Is there a way without cast (int (*)[3]) and why does the syntax differ from the function parameter?
So this is the work-around I want to avoid:
#include <stdio.h>
static int testArr[2][3] = {{0,1,2},{10,11,12}};
typedef struct {
int *arr2d;
} Foobar_t;
int main( int argc, char** argv ) {
Foobar_t foobar = {(int*)testArr};
int (*arr2d)[3] = (int (*)[3]) foobar.arr2d;
printf("testStruct_0_0: %d\n", arr2d[0][0]);
printf("testStruct_1_0: %d\n", arr2d[1][0]);
return 1337;
}
Edit:
Some comments suggest that reference is not the correct word. Of course in the C language this is implemented by a pointer. So the TLDR of this questions is: How does the syntax for a pointer type to a multi dimensional array look like.
The answer can already be seen in my work-around code. So that is all, move along, nothing to see here ;) Nevertheless thanks for the replies.
dummymember). And when you have a FAM, you have to dynamically allocate the structure with the correct amount of memory.Foobar_t foobar = {(int*)testArr};could be written more cleanly asFoobar_t foobar = { &testArr[0][0] };— no cast necessary. The second cast is not so easily avoided.dereference operator *used for?