Recently I was having a chat with my friend about standard way of
writing main function in C.
We were at loggerheads about whether there are any differences between
following two methods..
int main(void)
{ }
int main()
{ }
I think both are same....
Are they?
You should always use the first, with the addition of a proper return
statement of course. Following is some additional information about
the function main.
The implementation declares no prototype for main (and you should
never declare one either). The function main can be defined with no
parameters:
int main(void) { /* ...*/ }
or with two parameters:
int main(int argc, char *argv[]) { /* ... */ }
You can use any names for the two parameters, but you're better off
using the names above, as they're more or less universally used and
recognized by novice and experienced C programmers alike.
I can think of a few reasons for using main(void) over main(). First,
the C standard specifies main(void). Second, some compilers will issue
a warning for main().
/* foo.c */
int main()
{
return 0;
}
gcc -W -Wall -ansi -pedantic -Wstrict-prototypes foo.c -o foo
foo.c:3: warning: function declaration isn't a prototype
I know this is a benign warning for the above program, but I want my
source (perhaps hundreds of files) to compile with no warnings. Rather
than use main() and live with getting the above warning every time, I
just use main(void). Even if there is no difference between the two,
it's worth it to use main(void) to eliminate such potential warnings.
A third reason for using main(void) is that it is consistent with user
function prototypes and definitions that take no parameters. Consider
the following:
/* foo1.h */
int foo1();
/* foo1.c */
int foo1()
{
return 0;
}
/* foo2.h */
int foo2(void);
/* foo2.c */
int foo2(void)
{
return 0;
}
Every function you call should have a prototype in scope (or a
definition that is equivalent to having a prototype in scope). But
foo1() is not a prototype--it is a declaration that specifies foo1
takes zero or more arguments. The declaration for foo2 is a
prototype--it is a declaration that specifies foo2 takes zero
arguments.
Notice how the definition of foo2 is exactly the same as the prototype
of foo2. That's not a coincidence, because I simply copied the line in
foo2.h and pasted it in foo2.c and removed the semicolon. In my
opinion, the semicolon should be the only difference between the
prototype and the definition text. Copy-and-paste makes this an easy
convention to follow.
Which form of main you should use depends on whether or not you need
to use the argc and argv parameters. If you don't use argc and argv, I
suggest using main(void); otherwise, you may get warnings from
compilers and tools like PC-lint about unused arguments.
int main(int argc, char *argv[])
{
return 0;
}
VC++:
warning C4100: 'argv' : unreferenced formal parameter
warning C4100: 'argc' : unreferenced formal parameter
gcc:
warning: unused parameter 'argc'
warning: unused parameter 'argv'
PC-lint:
Info 715: Symbol 'argv' (line 1) not referenced
Info 715: Symbol 'argc' (line 1) not referenced
It's better to use main(void) instead to avoid these warnings.
Following is a simple example.
#include <stdio.h>
int main(void)
{
printf("Hello world!\n");
return 0;
}
Note that the return type of main is int. Also note that the above
program returns a value of 0. Returning a value of 0 from main results
in an implementation-defined form of the status successful termination
being returned to the host environment. If your main function always
returns a success status, I suggest returning a value of 0, as above.
However, if your main function is to return an unsuccessful status,
then you should return EXIT_FAILURE, which is a macro defined in
<stdlib.h>. The latter header also defines the macro EXIT_SUCCESS,
which can be used in place of 0 to indicate successful termination. In
other words, the following program is equivalent to the one above:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("Hello world!\n");
return EXIT_SUCCESS;
}
My preference is to return 0 if main does not return EXIT_FAILURE, and
EXIT_SUCCESS if it does. Of course it does not matter whether you
return EXIT_SUCCESS or 0, but I like the parallelism by using
EXIT_FAILURE and EXIT_SUCCESS, and I may not have to include
<stdlib.h> if I only return 0. For example:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int status;
if ( argc < 2 )
{
printf("No arguments supplied\n");
status = EXIT_FAILURE;
}
else
{
printf("argv[1] is %s\n", argv[1]);
status = EXIT_SUCCESS;
}
return status;
}
If you return any value other than 0, EXIT_SUCCESS or EXIT_FAILURE
from main, the status returned is implementation-defined.
Another note about main. You can use a call to exit (declared in
<stdlib.h>) instead of using a return statement, but I suggest never
doing this (in the function main; whether you call exit in other
places is debatable). The C standard states that "a return from the
initial call to the main function is equivalent to calling the exit
function with the value returned by the main function as its
argument". The following example, although acceptable, is just plain
silly, IMHO, because of the call to exit:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if ( argc < 2 )
{
printf("No arguments supplied\n");
exit(EXIT_FAILURE);
}
printf("argv[1] is %s\n", argv[1]);
return EXIT_SUCCESS;
}
One final note about the above: it necessarily applies only to a
hosted environment. The C standard defines two execution environments:
hosted and freestanding. In a freestanding environment, the
implementation is "free" to do things such as defining main with a
return type of void or even things like using a different name other
than main for the C function that is used for program startup.
Generally speaking, you'll be using a hosted environment if you're
using a desktop OS like Linux or Windows or Mac OS and using compilers
like gcc and Visual C++ that create programs that execute within these
environments. If you ever need to be concerned with a freestanding
environment, then you'll probably have enough experience to realize
that you're working with one. Freestanding environments are popular
with embedded development.
--
jay
http://www.ubuntu.com/
http://www.microsoft.com/express/vc/
http://www.gimpel.com/