Search code examples
carraysmultidimensional-arrayimplicit-conversion

Indirection in C with Multidimensional Arrays


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]'

Solution

  • 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 *.