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

Here is what is written as a rationale for adding a fantastic star syntax * to declare array types inside function prototypes - only before we get to the question:

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

But I'm sure that we can have the same effect simply by using only regular arrays with an indefinite size like this (here, rewriting the example function with the minimum name given in the quote above, with the exception of using size_t instead of int as the first parameter , which is not so 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 am sure that there was a place in the standard in which it is indicated that 2 arrays are compatible only if their size is equal and does not matter if they are variables or not.

My point is also confirmed by the fact that the definition of minimum will not complain about "conflicting types", as if some of its parameters had incompatible types (which, in my opinion, are not the same as both of these arrays have a size that is not specified in compilation time - I refer to the second parameter minimum ).

OK, besides, can you tell me one single use case for [*] , which cannot be replaced with ordinary arrays of unspecified sizes?

The above code compiles without any warning using both clang and gcc. It also gives the expected result.

For those who don’t know C (or anyone who thinks they know it), the parameter parameter of the type array function is implicitly converted to a "pointer to its element type". So:

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

Gets:

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

And then I argue that it can also be written as:

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

Without any consequences and with the same behavior as the 2 forms above. Thus, the form [*] out of date.

+5
source share
2 answers

OK, besides, can you tell me one single use case for [*], which cannot be replaced with ordinary arrays of unspecified sizes?

This will be the case when you pass a 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 undefined size:

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

But you don’t have the opportunity to omit or bypass the last index, so it should remain as [*] in such an ad.

+6
source

[] can only be used as the left-most "dimension specifier" of a multidimensional array, while [*] can be used anywhere.

In function parameter declarations, the leftmost (only!) [...] set to (*) in any case, therefore, you can use (*) in this position due to some clarity.

You can omit the measurement closest to the left [...] , leaving blank brackets. This will cause the array element type to be incomplete. This does not really matter, since you can complete it close to the point of use (for example, in the definition of a function).

The following [...] requires a number or * , inside of which it is impossible to miss. These ads

 int foo (int [*][*][*]); int foo (int (*)[*][*]); int foo (int (*)[ ][*]); 

all are compatible, but there is not one compatible with them that does not define the third dimension as either * or a number. If the third dimension is indeed a variable, * is the only option.

Thus, [*] necessary, at least for sizes 3 and above.

+6
source

All Articles