Reputation: 72639
I can't count the number of times I've seen C code out there and here on SO that defines main as
int main() { ...
When I compile it with
gcc -ansi -pedantic -Wstrict-prototypes -Werror foo.c
it errors out with
foo.c:2: warning: function declaration isn't a prototype
Why is it that
int main(void)
is required to make the error go away?
Upvotes: 4
Views: 6676
Reputation: 19662
It doesn't error - it warns. The flag says it all: it expects you to care about the arguments received by main
(typically int argc, char **argv)
.
Upvotes: 2
Reputation: 49393
As per the gcc documentation it's a warning when you added -Wstrict-prototypes
because:
-Wstrict-prototypes (C and Objective-C only)
Warn if a function is declared or defined without specifying the argument types. (An old-style function definition is permitted without a warning if preceded by a declaration that specifies the argument types.)
But for you it's an error because of -Werror
:
-Werror
Make all warnings into errors.
In general, it's wrong to define a main()
like that (regardless of what you've seen done on here), the C spec defines how main()
must look in 5.1.2.2.1:
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
Upvotes: 1
Reputation: 263257
Because the definition
int main() { /* ... */ }
does not include a prototype; it doesn't specify the number or type(s) of the parameters.
This:
int main(void) { /* ... */ }
does include a prototype.
With the empty parentheses, you're saying that main
takes a fixed but unspecified number and type(s) of arguments. With (void)
, you're explicitly saying that it takes no arguments.
With the former, a call like:
main(42);
will not necessarily be diagnosed.
This goes back to the pre-ANSI days before prototypes were introduced to the language, and most functions were defined with empty parentheses. Back then, it was perfectly legal to write:
int foo();
int foo(n)
int n;
{
/* ... */
}
...
foo(42);
When prototypes were added to the language (borrowed from C++), it was necessary to keep the old meaning of empty parentheses; the "new" (this was 1989) syntax (void)
was added so you could explicitly say that a function takes no arguments.
(C++ has different rules; it doesn't allow old-style non-prototyped functions, and empty parentheses mean that a function takes no arguments. C++ permits the (void)
syntax for compatibility with C, but it's not generally recommended.)
Best practice is to use (void)
, because it's more explicit. It's not entirely clear that the int main()
form is even valid, but I've never seen a compiler that doesn't accept it.
Upvotes: 8