Hi all,
I have heard many discussions among my colleagues that main is a user
defined function or not.
More exactly, the definition of main is user-defined. Its prototype is
not declared by the implementation, and it follows that you--the
user--must not declare its prototype.
Your definition of main must conform to the C Standard, which
specifies the following acceptable choices:
int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }
One of the most important things to notice about these definitions is
that main returns a type of int. Defining main to return any type
other than int is considered to be undefined behavior; some compilers
gladly accept a definition of main that defines a return type other
than int, such as void, but you should avoid using such a definition,
for the following reasons: 1) a return type other than int (e.g.,
void) is considered undefined behavior because it does not conform to
the C Standard, and 2) those same compilers will gladly accept a
return type of int, which does conform to the C Standard.
After you have defined your main function to return a type of int,
another important thing to keep in mind is that the actual value of
the return type can take on only a few specific values. These values
are 0, EXIT_SUCCESS and EXIT_FAILURE. Period. The latter two values
are macros defined in the Standard C header file <stdlib.h>. Returning
a value of 0 has the same effect as returning a value of EXIT_SUCCESS,
as far as the C Standard is concerned.
Whether or not you choose to return 0 or EXIT_SUCCESS from main is a
matter of preference and perhaps style. My preference is to return 0
if I never return an error status (i.e., EXIT_FAILURE) and return
EXIT_SUCCESS if I do return an error status. One benefit of this is
that for simple "Hello World!" programs, I can return 0 and do not
have to include <stdlib.h>. For example:
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
If I return EXIT_FAILURE somewhere, someplace, then my (pseudo)code
might look something like this:
#include <stdlib.h>
int main(void)
{
if ( /* some expression */ )
{
/* error */
return EXIT_FAILURE;
}
else
{
/* success */
return EXIT_SUCCESS;
}
}
One final note about the function main. Sometimes its return type of
int simply does not make sense. Most if not all embedded software
written in C has a main function that looks something like this:
int main(void)
{
/* initialize stuff */
for ( ; ; )
{
/* do something */
}
return 0;
}
As long as the "do something" part does not contain a break statement
(which is hardly if never the case), the return statement will never
be executed. In that sense, and in the sense that there is no
environment to which to return a value on many if not most embedded
applications, it doesn't really make sense to define main to return a
type of int, does it? Some compilers and source code analyzers will
flag a warning about the return statement in the above example, saying
something to the extent that it is unreachable code. What really makes
the most sense in this instance is that the return type of main is
void, e.g.:
void main(void)
{
/* initialize stuff */
for ( ; ; )
{
/* do something */
}
}
If and when you ever run into such a situation, just make sure that
your compiler provides the option to define main with a return type of
void. Of course your code will be non-portable, but you should only be
using such compiler-specific options in an application domain such as
the embedded world, which is highly non-portable (though not totally
non-portable), especially for any non-trivial application.
Best regards