1

I would like to execute something like the following code, but I keep getting a warning for levels of indirection.

It is my understanding that in the following,

int Array1[5];
int Array2[2][4];
int *pointer1 = Array1;
int *pointer2 = Array2;

all 4 examples have the level of indirection of (int*).

But it seems like no matter what combination of the following ideas I try to compile the code, I get indirection warnings:

void loadIntArrayData(int size, int *buffer);

void passArrayIntoThisFunction(char count, int *structure){     //idea 1
void passArrayIntoThisFunction(char count, int **structure){    //idea 2
void passArrayIntoThisFunction(char count, int structure[][3]){ //idea 3
    loadIntArrayData(3*count*sizeof(int), structure);          //idea 1
    loadIntArrayData(3*count*sizeof(int), &(structure[0][0])); //idea 2
    loadIntArrayData(3*count*sizeof(int), &(structure[0]));    //idea 3
    loadIntArrayData(3*count*sizeof(int), structure[0]);       //idea 4
}

int main(void){
    passArrayIntoThisFunction(2, (int[][3]){{1,2,3},{4,5,6}});
    //I want to have a multi-level array ^ here ^ for readability
    return 0;
}

Could someone explain levels of indirection when it comes to multi-dimensional arrays?

Here is the warning (small variations depending on which combination used):

'function': 'int *' differs in levels of indirection from 'int[2][3]'
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
ilcj
  • 127
  • 10
  • 1
    You have pointer type mismatches. Don't even try to run the code until you eliminate them all. The assignment to `pointer2` should generate an incompatible pointer warning, since you're trying to assign an `int (*)[4]` to an `int *`. If you want to declare `pointer2` properly, declare it as `int (*pointer2)[4];` Then you can access `Array2` through `pointer2` properly. – Tom Karzes Jun 09 '20 at 19:11
  • Does this answer your question? [C pointer to array/array of pointers disambiguation](https://stackoverflow.com/questions/859634/c-pointer-to-array-array-of-pointers-disambiguation) – Tom Karzes Jun 09 '20 at 19:13

2 Answers2

2

In C, the name of an array decays to the pointer of its first element in all cases but three: usage of the & (address-of) operator, usage of the sizeof operator, and literal string initialization (e.g. char a[] = "foobar";)

Therefore, in int *pointer2 = Array2; your Array2 decays to a int (*)[] (pointer-to-array-of-int) and not an int *.

1

If you have an array like for example this

int Array2[2][4];

when used in expressions (with rare exceptions) in particularly as an initializer it is converted to pointer to its first element. The elements of the array have the type int[4]. So a pointer to the first element of the array will have the type int( * )[4].

Thus you may write

int Array2[2][4];

int ( *pointer2 )[4] = Array2;

As for this function declaration

void passArrayIntoThisFunction(char count, int structure[][3]);

and its call

passArrayIntoThisFunction(2, (int[][3]){{1,2,3},{4,5,6}});

then the compound literal used as an argument has the type int ( * )[3] and the corresponfing function parameter is adjusted by the compiler to int ( *structure )[3].

So if you want to pass this pointer further to another function then either a corresponding parameter of the function must have the same type or it can have the type int * but in this case you have explicitly to cast the passed pointer to the type int *.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Thank you. Your information about explicit casting from array pointers was helpful. – ilcj Jun 09 '20 at 19:25