6.7.6.3 Function declarators (including prototypes)
This part of the standard deals with \'Identifier list\' and \'Parameter typ
Function declaration is not the same as function prototype. Prototype is a special kind of declaration. For example, this is a function declaration that is not a prototype
int foo();
And the following declarations are prototypes
int foo(int a, double b);
int bar(char, float);
float baz(void);
I.e. prototype is a declaration that describes the number and the types of function parameters. A non-prototype declaration does not say anything about parameters.
Now, C language still supports old K&R-style function definitions in addition to "modern" function definitions. K&R-style function definition looks as follows
int foo(a, b)
int a;
double b;
{
...
}
A "modern" function definition looks as follows
int foo(int a, double b)
{
...
}
As you can see, the K&R-style parameter list is just a, b. It includes parameter names, but does not include their types. This is what the grammar refers to as identifier-list. The "modern" parameter list is int a, double b and this is what the grammar refers to as parameter-type-list.
I.e. identifier-list is a part of K&R-style function definition syntax, while parameter-type-list is a part of "modern" function definition syntax.
Note also that in C language the declaration
int foo();
does not mean that foo takes no arguments. It means that foo take an unspecified number of arguments, i.e. it simply turns off argument type checking, argument number checking and argument conversions for foo at the point of the call. Such "signature" will match a definition for foo with any parameter list. This
int foo(int x)
{
...
}
is a perfectly valid definition for foo declared as shown above. The fact that it is declared with () simply means that the compiler will not verify the arguments at the point of the call. It will be your responsibility to make sure that you are calling foo with exactly one argument of int type.