Search code examples
cmatrixmultidimensional-arraystaticreturn-type

How to return a multidimensional static array from a function in c


I want to return a multidimensional matrix from a function.

So I know how to do that through a struct and dynamic allocating. But I'm not sure how to do that with a static multidimensional array.

#include <stdio.h>
static int **function(){
    static int array[5][10];
    return array;
}
int main(void){
    int** test;
    test = function();
    return 0;
}

The Gcc keep emiting this warning:

Warning: returning 'int (*)[10]' from a function with incompatible return type 'int **' [-Wincompatible-pointer-types] return array;

And I want to understand why?


Solution

  • In this return statement

    return array;
    

    the array designator array is converted to pointer to its first element of the type int ( * )[10]. But the function return type is int **. There is no implicit conversion from the type int ( * )[10] to the type int **. So the compiler will issue an error.

    Pay attention to that the user of the function needs to know the sizes of the array.

    So I advise you to declare the function like

    static int ( *function( void ) )[5][10]
    {
        static int array[5][10];
        return &array;
    }
    

    and then in main you can write

    int ( *test )[5][10] = function();
    

    dereferencing the pointer test you will get the array.

    Here is a demonstrative program.

    #include <stdio.h>
    
    enum { M = 5, N = 10 };
    
    static int ( *function( void ) )[M][N] 
    {
        static int array[M][N] =
        {
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
            { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
            { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
            { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }
        };
        
        return &array;
    }
    
    int main(void) 
    {
        int ( *test )[M][N] = function();
        
        printf( "The size of the array is %zu\n", sizeof( *test ) );
        
        for ( size_t i = 0; i < M; i++ )
        {
            for ( size_t j = 0; j < N; j++ )
            {
                printf( "%d ", ( *test )[i][j] );
            }
            putchar( '\n' );
        }
        
        return 0;
    }
    

    The program output is

    The size of the array is 200
    1 1 1 1 1 1 1 1 1 1 
    2 2 2 2 2 2 2 2 2 2 
    3 3 3 3 3 3 3 3 3 3 
    4 4 4 4 4 4 4 4 4 4 
    5 5 5 5 5 5 5 5 5 5
    

    You can introduce an alias for the array type the following way to make the function declaration simpler

    #include <stdio.h>
    
    enum { M = 5, N = 10 };
    
    typedef int Array[M][N];
    
    static Array * function( void ) 
    {
        static Array array =
        {
            { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
            { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
            { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
            { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
            { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }
        };
        
        return &array;
    }
    
    int main(void) 
    {
        Array *test = function();
        
        printf( "The size of the array is %zu\n", sizeof( *test ) );
        
        for ( size_t i = 0; i < M; i++ )
        {
            for ( size_t j = 0; j < N; j++ )
            {
                printf( "%d ", ( *test )[i][j] );
            }
            putchar( '\n' );
        }
        
        return 0;
    }