I'm trying to understand declarations, definitions and prototypes. I came across the excellent post https://stackoverflow.com/a/41805712/1825603. I do, however, need some clarification, but because I do not have enough reputation to comment directly to the post, I will ask here...
The relevant section:
In definitions
void func1() { } // obsolescent
and
void func2(void) { }
The former declares and defines a function func1 that has no parameters and no prototype
The latter declares and defines a function func2 with a prototype that has no parameters.
When I see int main(void) { }
as one of the Standard definitions for main in C99 5.1.2.2.1, I interpret from the above that it's "a declaration and definition of a function with a prototype that has no parameters". My confusion lies with C99 5.1.2.2.1, where it says, "The implementation declares no prototype for this function." By adding the void
to int main() { }
, does this mean the user-level code is declaring a prototype because the implementation hasn't? And if it's not a prototype, what is the effect of adding void
?
Note: I believe I understand the reason the declaration int main(void);
isn't used, ie, Declare main prototype, but don't think my question is a duplicate of this.
CodePudding user response:
C 2018 6.2.1 2 says:
… ((A function prototype is a declaration of a function that declares the types of its parameters.)
Thus int main(int argc, char *argv[]);
is a function prototype, because it declares the types of its parameters, argc
and argv
.
int main(int argc, char *argv[]) {}
is also a function prototype. Even thought it is a function definition, it also declares the function.
Functions can be defined with an old style that did not have declarations in the parameter list, such as:
int main(argc, argv)
int argc;
char *argv[];
{
}
Although the types of the parameters are declared in the declaration list between the function declarator and the body of the function, this is not what the C standard means by declaring the types of the parameters. This phrasing in the C standard is unfortunately imprecise, but the intent is that a “function prototype” is a declaration of the modern form with the types specified in the parameter list, contrasted with the legacy form with only the parameter names in the list.
We can see this because C 2018 6.2.7 3 distinguishes a function prototype as a function declared with a parameter type list rather than a simple identifier list:
… a function type with a parameter type list (a function prototype)…
Also note the special form (void)
, as in int foo(void)
, counts as a function prototype as a special case; it is the modern form of declaration that asserts the function has no parameters. The old form int foo();
does not specify whether the function has parameters or not.