Reputation: 421
I know that in modern C when we declare a function that has no parameter we must specify the void keyword like :
int fx(void);
However I have some doubts when it comes to function definitions. For example, are these two definitions the same ?
int fx(){} /* it is as if it was void */
int fx(void){}
I guess these two definitions are the same because I see a lot of code out there that omit the void keyword in the parameter....
Upvotes: 0
Views: 133
Reputation: 311088
Before the C23 Standard you may declare a function with a parameter type list or identifier list.
In this example of function declarations that are at the same time function definitions
int fx(){} /* it is as if it was void */
int fx(void){}
The first function declaration has an empty identifier list and the second function declaration has a parameter list with an unnamed parameter of the type void
specifying that the function has no parameters. The second declaration provides a function prototype.
A question is raised relative to whether you may mix such declarations. For example, whether these declarations are correct
int fx( void );
int fx(){}
According to the C17 Standard (6.7.6.3 Function declarators (including prototypes))"
3 An identifier list in a function declarator that is not part of a definition of that function shall be empty.
and
14 An identifier list declares only the identifiers of the parameters of the function. An empty list in a function declarator that is part of a definition of that function specifies that the function has no parameters. The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied.
So as the function declaration that at the same time is its definition has an empty identifier list then and its declaration that is not at the same time is its definition shall also have an empty identifier list.
You may not mix function declarations of the same function with an identifier list and with parameter type list.
The C23 Standard removed the support for function definitions with identifier lists.
According to the C23 Standard (6.7.6.3 Function declarators)
13 For a function declarator without a parameter type list: the effect is as if it were declared with a parameter type list consisting of the keyword void. A function declarator provides a prototype for the function
And there is a footnote (174):
)This implies that a function definition without a parameter list provides a prototype, and that subsequent calls to that function in the same translation unit are constrained not to provide any argument to the function call. Thus a definition of a function without parameter list and one that has such a list consisting of the keyword void are fully equivalent.
Upvotes: 2
Reputation: 11377
With void
you get an error if parameters are passed to the function:
$ cat t.c
int fx()
{
return 0;
}
int fx1(void)
{
return 0;
}
int main(void)
{
fx(0);
fx1(0);
return 0;
}
$ gcc -pedantic -std=c89 -Wall t.c
t.c: In function ‘main’:
t.c:14:9: error: too many arguments to function ‘fx1’
14 | fx1(0);
| ^~~
t.c:6:5: note: declared here
6 | int fx1(void)
| ^~~
Edit: Declaring fx
with the signature int fx(void)
and defining it with the signature int fx()
, and declaring fx1
with the signature int fx()
and defining it with the signature int fx(void)
will signal two errors in the code above. Therefor the most restrictive signature takes precedence over the other.
Upvotes: 1
Reputation: 1842
Before C23, if the parameter is void
in the declaration, the compiler will be able to detect an error if the function is called with some parameter :
int fx(void);
int main(int argc, char **argv) {
fx(1); // -> will produce an error at compile time
return 0;
}
On the other hand, if there's no parameter in declaration, the compiler won't check parameters on function call :
int fx();
int main(int argc, char **argv) {
fx(1, 2); // -> no error here
return 0;
}
Upvotes: -1