1

I must pass to a function a pointer on a bi-dimensional array of integers (which is actually a Life game grid). This function has no way to know the width and height. What should be the function prototype?
I tried:

int function(int (*grid)[][], int height, int width);

which results in an error: 'array type has incomplete element type'
I can't figure out any other way to do it whithout knowing array dimensions.

(A bit of explanation: the width and height of the grid are #define 'd in the main.c file, and the function prototype I need is in a header file, so it can't access this #define...)

Thank you

Magix
  • 3,557
  • 3
  • 18
  • 43

2 Answers2

2

Unless you are using MS Visual Studio 2013 Express as I do, as well as have a C99 standard compliant compiler in your hands, you can do the following:

int function( int height, int width, int (*grid)[height][width] );

All you need is the variable-length arrays (VLA) functionality, which the semi-compliant MSVC lacks. Here's an example usage of it: http://ideone.com/J3y2oi

Utkan Gezer
  • 2,794
  • 1
  • 11
  • 27
  • This works! But I never heard about VLA functionality, have you got documents/references on that subject? that would be great :) thank you – Magix Jul 12 '14 at 00:48
  • You could reach for the search box at the top of the page and type '`[c] variable length array`'. The very first question in the list actually isn't dreadfully relevant (it details a minute but important issue as part of an answer about `sizeof()`), but many of the other questions are relevant. There are also a lot of closely related questions -- possible duplicates -- listed in the 'related questions' list at the RHS of the page. – Jonathan Leffler Jul 12 '14 at 00:54
1

If you have a C99 or C11 compiler available, then you can pass both dimensions of the array as arguments before the array parameter, as shown in ThoAppelsin's answer.

If you are stuck with a C89 compiler, then you have to work harder — much harder. By far the simplest solution is to make the #define dimensions available in the header; then you can write:

int function(grid[HEIGHT][WIDTH]) { ... }
int function(grid[][WIDTH]) { ... }

If you can't do that, then you'll have to think about modifying either the code in the function or the data structures in main.c.

Modifying the function means:

int function(int height, int width, int *grid)
{
    int i, j;
    for (i = 0; i < height; i++)
        for (j = 0; j < width; j++)
            grid[i*width + j] = 0;
    return j;
}

This takes an ordinary pointer-to-int and does the index calculations explicitly, rather than simply writing two subscripts. Your main code might have:

int grid[HEIGHT][WIDTH];

i = function(HEIGHT, WIDTH, &grid[0][0]);

The alternative is that you create a secondary structure, a set of pointers to pointers, in main():

int grid_rows[HEIGHT];
for (i = 0; i < HEIGHT; i++)
    grid_row[i] = grid[i];

i = function(HEIGHT, WIDTH, grid_rows);

Now the definition is:

int function(int height, int width, int **grid)
{
    int i, j;
    for (i = 0; i < height; i++)
        for (j = 0; j < width; j++)
            grid[i][j] = 0;
    return j;
}

This reinstates the notational convenience in the function at the cost of the extra storage and initialization.

Community
  • 1
  • 1
Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185