The main reason to add an array size is for documentation purposes. Also, with C99, you can add qualifiers within the square brackets which will be used to modify the pointer declaration to which the array declaration will be converted if it occurs within a parameter list.
See C99 spec, section 6.7.5.3, §7:
A declaration of a parameter as
‘‘array of type’’ shall be adjusted to
‘‘qualified pointer to type’’, where
the type qualifiers (if any) are those
specified within the [ and ] of the
array type derivation. If the keyword
static also appears within the [ and ]
of the array type derivation, then for
each call to the function, the value
of the corresponding actual argument
shall provide access to the first
element of an array with at least as
many elements as specified by the size
expression.
and §21:
EXAMPLE 5 The following are all
compatible function prototype
declarators.
double maximum(int n, int m, double a[n][m]);
double maximum(int n, int m, double a[*][*]);
double maximum(int n, int m, double a[ ][*]);
double maximum(int n, int m, double a[ ][m]);
as are:
void f(double (* restrict a)[5]);
void f(double a[restrict][5]);
void f(double a[restrict 3][5]);
void f(double a[restrict static 3][5]);
(Note that the last declaration also specifies that the argument corresponding to a in any call to f must be a
non-null pointer to the first of at least three arrays of 5 doubles, which the others do not.)