Ommiting parameter names in prototypes is typically done for defensive purposes.If a macro happens to have the same name as a parameter , the parameter name will be replaced during preprocessing , thereby damaging the prototype in which it appears. This isn't likely to be a problem in a small program writeen by one person but can occur in large applications writen by many people.
This is an entirely bogus reason as you've already spotted. If the parameter name would be screwed up in the prototype, then it's also going to get screwed up in the same way in the function definition.
By convention, macro names (and only macro names) are written in UPPERCASE, so the problem of unexpected prototype parameter name substitution never applies.
> To be sincere is more natural and convenient to me when I write code keep the names away from prototypes.
Which would you rather see in a header file?
int findsubstring ( char*, char* );
vs.
int findsubstring ( char*needle, char*haystack );
Personally, I prefer the second, since it's instantly obvious which way round the parameters are. A bare prototype means you're off trying to find the documentation (or the source code).
Further, if you wrote
Code:
int findsubstring ( char*needle, char*haystack ) {
// code goes here
}
then it's a simple copy/paste to make the prototype
int findsubstring ( char*needle, char*haystack );
Why waste further edit time (and the chance of screwing up the edit in some way) just to make the prototype less readable?
> Another issue is the symbol (*) Kings says that provides a clue that the length of the array is related to parameters that come earlier in the list ... what is this?
To be honest, I thought it was a mistake until I looked it up in the standard.
Personally, I can't see what it does which is of any benefit over just leaving the size empty.
I mean, "an earlier parameter" doesn't mean a thing if you're faced with
void func ( int n, int len, int arr[*] );
or worse
void func ( int, int, int[*] );
I wonder which int controls the array length here?
Every competent C programmer knows that arrays are just pointers, so there has to be another parameter specifying the size of the array if the function has any hope of being written in a safe manner.
The compiler simply doesn't care about the left-most dimension in function array parameters.
Code:
#include<stdio.h>
#include<stdlib.h>
void fill_array1( int n, int arr[*]);
void fill_array2( int n, int arr[]);
void fill_array3( int n, int arr[5]);
void fill_array4( int n, int arr[n]);
void fill_array5( int n, int *arr);
void fill_array1( int n, int arr[/* can't use a * here? */] ) {
printf("%zd\n", sizeof(arr) );
for ( int i = 0 ; i < n ; i++ ) arr[i] = i;
}
void fill_array2( int n, int arr[] ) {
printf("%zd\n", sizeof(arr) );
for ( int i = 0 ; i < n ; i++ ) arr[i] = i;
}
void fill_array3( int n, int arr[5] ) {
printf("%zd\n", sizeof(arr) );
for ( int i = 0 ; i < n ; i++ ) arr[i] = i;
}
void fill_array4( int n, int arr[n] ) {
printf("%zd\n", sizeof(arr) );
for ( int i = 0 ; i < n ; i++ ) arr[i] = i;
}
void fill_array5( int n, int *arr ) {
printf("%zd\n", sizeof(arr) );
for ( int i = 0 ; i < n ; i++ ) arr[i] = i;
}
int main()
{
int a[20];
fill_array1(20,a);
fill_array2(20,a);
fill_array3(20,a);
fill_array4(20,a);
fill_array5(20,a);
return 0;
}
$ gcc -std=c99 -W -Wall bar.c
$ ./a.out
8
8
8
8
8
> bar.c:10:1: error: ‘[*]’ not allowed in other than function prototype scope
This shows a couple of things.
1. the[*] notation is a pointless exercise away from copy/pasting definition to prototype.
2. no matter how you write your array parameter, it won't magically transform it into something else - it is and remains just a pointer.