Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In a C header file I saw `[*]` used as array bound. What does this mean?

Tags:

arrays

c

In one of our files I saw this function

void match(int states[*]);

I have never seen such a thing in C. Can someone please explain that what this weird operator in the brackets mean?

like image 299
Johannes Schaub - litb Avatar asked Oct 15 '11 23:10

Johannes Schaub - litb


2 Answers

This is syntax that was new in C99. It is valid only for a parameter in a function declaration that is not also a definition. It indicates a variable-length array of unspecified length; in this case, since it is at the top level, it is (as usual) completely equivalent to int states[] and int *states.

This syntax is useful if a pointer to an array is passed - for example, if we have a function like:

void foo(size_t n, int a[][n])
{
    /* ... */
}

..then we can write a compatible declaration that provides a prototype as either:

void foo(size_t n, int a[][n]);

or as:

void foo(size_t, int a[][*]);

These are completely equivalent.

(By the way, the * there is not an operator, it is just punctuation.)

like image 153
caf Avatar answered Oct 22 '22 01:10

caf


[*] denotes a C99 variable-length array of unspecified size, which is only valid in prototypes, but nevertheless a complete type (ie distinct from [], which denotes an incomplete array type).

Your example, however, makes no sense. A more reasonable example would be

// in header file:
void match(size_t, int *[*]);

// in source file:
void match(size_t count, int *states[count])
{
    // ...
}

As the parameter names are omitted, the array declaration can't refer to the first argument, so a placeholder had to be introduced.

However, as parameter adjustments still get applied, the prototype is identical to

void match(size_t, int **);

and the array type information is discarded.

This is not the case for higher indices of multi-dimensional arrays, eg

double det(size_t rows, size_t cols, double mat[rows][cols]);

only discards the rows, ie the declaration is equivalent to

double det(size_t rows, size_t cols, double mat[][cols]);

and

double det(size_t rows, size_t cols, double (*mat)[cols]);

which in turn correspond to the following compatible declarations

double det(size_t, size_t, double [*][*]);
double det(size_t, size_t, double [][*]);
double det(size_t, size_t, double (*)[*]);

To prevent the parameter adjustment, pass a pointer to the array instead, ie

double det(size_t rows, size_t cols, double (*mat)[rows][cols])

Then, sizeof *mat should return the expected value within the function body.

like image 33
Christoph Avatar answered Oct 22 '22 02:10

Christoph