Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with int main()?

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?

like image 859
Jens Avatar asked Dec 21 '22 07:12

Jens


1 Answers

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.

like image 185
Keith Thompson Avatar answered Dec 24 '22 01:12

Keith Thompson