Jens
Jens

Reputation: 72639

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?

Upvotes: 4

Views: 6676

Answers (3)

Sébastien Renauld
Sébastien Renauld

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

Mike
Mike

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

Keith Thompson
Keith Thompson

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

Related Questions