Search code examples
cmultidimensional-arrayreturn-typefunction-declaration

How to return a statically allocated two-dimensional array in C?


I have the following code in spbox.c:

#include <stdbool.h>
#include <stdint.h>

typedef struct {
    bool initialized;
    uint32_t Spbox[8][64]; // Combined S and P boxes
} spboxState;

static spboxState stateInstance;

uint32_t ** desGetSpbox(void) {
    if (!(stateInstance.initialized)) {
        // TODO: Compute data to populate Spbox array
        stateInstance.initialized = true;
    }
    return stateInstance.Spbox;
}

I compile it:

clang -c spbox.c

I get a warning about incompatible pointer return types:

spbox.c:16:9: warning: incompatible pointer types returning 'uint32_t [8][64]' from a function with result type 'uint32_t **' (aka 'unsigned int **') [-Wincompatible-pointer-types]
        return stateInstance.Spbox;
               ^~~~~~~~~~~~~~~~~~~
1 warning generated.

How do I change my code to make the warning go away? It is saying that uint32_t ** isn't compatible with uint32_t [8][64]. But if I try to make the later the return type, I get a syntax error.


Solution

  • You may not return an array. But you may return a pointer to an array or its first element.

    For example

    uint32_t ( * desGetSpbox(void) )[8][64] {
        if (!(stateInstance.initialized)) {
            // TODO: Compute data to populate Spbox array
            stateInstance.initialized = true;
        }
        return &stateInstance.Spbox;
    }
    

    Or

    uint32_t ( * desGetSpbox(void) )[64] {
        if (!(stateInstance.initialized)) {
            // TODO: Compute data to populate Spbox array
            stateInstance.initialized = true;
        }
        return stateInstance.Spbox;
    }
    

    Here is a demonstrative program

    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include <inttypes.h>
    
    enum { M = 8, N = 64 };
    
    typedef struct {
        bool initialized;
        uint32_t Spbox[M][N]; // Combined S and P boxes
    } spboxState;
    
    static spboxState stateInstance;
    
    uint32_t ( *desGetSpbox1( void ) )[M][N] 
    {
        stateInstance.Spbox[0][0] = 10;
        return &stateInstance.Spbox;
    }
    
    uint32_t ( *desGetSpbox2( void ) )[N] 
    {
        stateInstance.Spbox[0][0] = 10;
        return stateInstance.Spbox;
    }
    
    
    int main(void) 
    {
        uint32_t ( *p1 )[M][N] = desGetSpbox1();
        
        printf( "%" PRIu32 "\n", ( *p1 )[0][0] );
    
        uint32_t ( *p2 )[N] = desGetSpbox2();
        
        printf( "%" PRIu32 "\n", ( *p2 )[0] );
    
        return 0;
    }
    

    The program output is

    10
    10