carrayslanguage-lawyerc99

Why use "[*]" instead of "[]" in function prototype?


Here is what is it written as rationale for adding the fancy * star syntax for declaring array types inside function prototypes - just for clarification before we get into the question:

A function prototype can have parameters that have variable length array types (§6.7.5.2) using a special syntax as in int minimum(int,int [*][*]); This is consistent with other C prototypes where the name of the parameter need not be specified.

But I'm pretty confident that we can have the same effect by simply using only ordinary arrays with unspecified size like this (here re-writing the function example named minimum given above in the quote with what I believe exactly the same functionality (except for using size_t instead of int as first parameter which isn't that important in the case)):

#include <stdio.h>


int minimum(size_t, int (*)[]);

int (main)()
{
    size_t sz;

    scanf("%zu", &sz);

    int vla[sz];

    for(size_t i = 0; i < sz; ++i)
        vla[i] = i;

    minimum(sizeof(vla) / sizeof(*vla), &vla);

    int a[] = { 5, 4, 3, 2, 1, 0 };

    minimum(sizeof(a) / sizeof(*a), &a);
}


int minimum(size_t a, int (*b)[a])
{  
    for(size_t i = 0; i < sizeof(*b) / sizeof(**b); ++i)
        printf("%d ", (*b)[i]);

    return printf("\n");
}

Because I'm pretty sure that there was some place in the standard stating that 2 arrays are compatible only if their size are equal and no-matter if they are variable or not.

My point is also confirmed by the fact that the minimum definition wouldn't complain for "conflicting types" as it would if some of it's parameters had incompatible types (which I don't think is the case as both of those arrays have size which is unspecified at compile-time - I refer to the second parameter of minimum).

OK besides - can you point me 1 single use-case for [*] that can not be replaced using ordinary unspecified size arrays?

The above code compiles without any warnings using both clang and gcc. It also produces the expected output.

For anyone who doesn't know C (or anyone who thinks that he/she knows it) - function parameter of type array is implicitly transformed to "pointer to its elements type". So this:

int minimum(int,int [*][*]);

Gets adjusted to:

int minimum(int,int (*)[*]);

And then I'm arguing that it could be also written as:

int minimum(int,int (*)[]);

Without any consequences and with the same behavior as the 2 forms above. Thus making the [*] form obsolete.


Solution

  • OK besides - can you point me 1 single use-case for [*] that can not be replaced using ordinary unspecified size arrays?

    This would be the case, when you pass three-dimensional VLA array:

    int minimum(size_t, int [*][*][*]);
    

    This can be written as:

    int minimum(size_t, int (*)[*][*]);
    

    or even using an array of unspecified size:

    int minimum(size_t, int (*)[][*]);
    

    But you have no way to omit nor get around the last index, so it has to stay as [*] in such a declaration.