The following has been valid in C89
main() {
return 0;
}
But in modern C (C99), this isn't allowed anymore because you need to explicitly tell the type of variables and return type of functions, so it becomes
int main() {
return 0;
}
Also, it's legal to omit the return 0
in modern C, so it is legal to write
int main() {
}
And the behavior is as if it returned 0.
People put void
between the parentheses because it ensures proper typechecking for function calls. An empty set of parentheses in C mean that no information about the amount and type of the parameters are exposed outside of the function, and the caller has to exactly know these.
void f();
/* defined as void f(int a) { } later in a different unit */
int main() {
f("foo");
}
The call to f
causes undefined behavior, because the compiler can't verify the type of the argument against what f
expects in the other modules. If you were to write it with void
or with int
, the compiler would know
void f(int); /* only int arguments accepted! */
int main(void) {
f("foo"); /* 'char*' isn't 'int'! */
}
So for main
it's just a good habit to put void
there since it's good to do it elsewhere. In C you are allowed to recursively call main
in which case such differences may even matter.
Sadly, only a few compilers support modern C, so on many C compilers you may still get warnings for using modern C features.
Also, you may see programs to declare main
to return different things than int
. Such programs can do that if they use a freestanding C implementation. Such C implementations do not impose any restrictions on main
since they don't even know or require such a function in the first place. But to have a common and portable interface to the program's entry point, the C specification requires strictly conforming programs to declare main with return type int
, and require hosted C implementations to accept such programs.