As long as you are working with single-dimensional arrays only, the above declarations are all equivalent. The last one though
void f(int i, int a[static i])
has an extra effect. It is equivalent to the previous ones in terms of the parameter types, but also tells the compiler that it can rely on a
parameter pointing to an array of at least i
elements (which can be used in optimizations).
You are also forgetting another new declaration
void f(int i, int a[const])
This one actually does have an effect even in case of a single-dimensional array. It is equivalent to
void f(int i, int *const a)
although some might argue that const-qualifications on function parameters are useless. Before it was impossible to const-qualify the pointer the array parameter "decays" to when using the []
syntax for the declaration.
The *
(as well as i
) between the []
begins to matter only when it is used between the second (or greater) pair of []
in multi-dimensional array declaration. In essence, it is just like it has always been: array size in the parameter declaration always mattered only between the second or further pair of []
. The *
is used in prototype declarations for VLA parameters, when the size value is not named explicitly. For example, you can declare
void bar(int n, int m, int a[n][m]);
and the compiler will know that a
is a VLA since the sizes are not constants. But if you prefer not to name parameters in prototypes, how are you going to tell the compiler that a
is a VLA? That's when *
helps
void bar(int, int, int a[*][*]);