Search code examples
cpointersmultidimensional-arrayimplicit-conversionpointer-to-array

Warnings of Pointer to array of matrices In ANSI C GCC C90


I'm having strange warnings in Linux. In Visual Studio on Windows, the code compiles and works well but I need to compile it with GCC c90 I get these warnings:

I've initialized the matrix like this:

typedef float mat[4][4];

Now i want to create an array of matrices:

mat MAT_A = { 0 };
mat MAT_B = { 0 };
mat MAT_C = { 0 };
mat *matrices[3] = {MAT_A, MAT_B, MAT_C};

I've declared the function:

void get_input(mat** matrices);

and use it:

get_input(&matrices);

The code is working well but I need to compile it with gcc c90. And I get this warnings:

warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]  
mat *(*matrices)[3] = {MAT_A, MAT_B, MAT_C};                     
                       ^~~~~

and

warning: passing argument 1 of ‘get_input’ from incompatible pointer type [-Wincompatible-pointer-types]
    flag = get_input(&matrices);
                     ^

Solution

  • Due to this typedef declaration

    typedef float mat[4][4];
    

    arrays declared like

    mat MAT_A = { 0 };
    

    are implicitly converted to its first element in this declaration

    mat *matrices[3] = {MAT_A, MAT_B, MAT_C};
    

    of the type float( * )[4]. But the variable matrices is declared as having the element type float ( * )[4][4]. These types are not compatible.

    That is in fact you have the following declaration

    float ( *matrices[3] )[4][4] = {MAT_A, MAT_B, MAT_C};
    

    You should declare the array eother like

    float ( *matrices[3] )[4] = {MAT_A, MAT_B, MAT_C};
    

    In this case the function should be declared like

    void get_input( float ( ** matrices)[4] );
    

    and called like

    get_input( matrices );
    

    or like

    mat *matrices[3] = { &MAT_A, &MAT_B, &MAT_C };
    

    in the last case the function is called like

    get_input( matrices );
    

    Also the function get_input declared like

    void() get_input(mat** matrices);
    

    actually is equivalent to

    void() get_input( float ( ** matrices )[4][4]);
    

    But in this call of the function

    get_input(&matrices);
    

    the argument has the type

    float( * ( * ) [3])[4][4]