The Controversy About void main() - BunksAllowed

BunksAllowed is an effort to facilitate Self Learning process through the provision of quality tutorials.

Random Posts

The Controversy About void main()

Share This
The main() function in C Language is the program's starting point. In different books and tutorials, you may get different signatures of the main function, like void main(), int main(), int main(int argc, char* argv[]), etc. However, you will be suggested to use the return type int. If you use any other return type for the main(), in pre-C99 compilers, you get undefined behavior. In C99 compilers, you get unspecified behavior if the implementation says so, or undefined behavior if it doesn't.

To write code for different environments, you should use one of the following definitions. The immediate following definition is preferred if the main function does not receive any parameter.
int main(void) { /* ... */ }

The alternate definition is preferred if the function receives command line arguments, as presented below:
int main(int argc, char *argv[]) { /* ... */ }

If the return type of the main function is a type compatible with int, 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; reaching the } that terminates the main function returns a value of 0. 

If the return type is not compatible with int, the termination status returned to the host environment is unspecified. In this context, unspecified means that the standard does not require any specific behavior from the compiler, which is free to return any status it likes to the host environment (typically the operating system), and this only applies if the implementation documents the fact that it supports other return types from main() other than int.

If you write void main() and you're writing code for a nuclear reactor or a military aircraft, you're probably feeling a little unsettled right now. 

Furthermore, defining main() to return void is not a syntax error or a constraint violation, so the compiler is not obligated to generate a diagnostic message.


You're not responsible for defining main()'s interface. The primary customer for main() is the startup code. Hence, how can the startup code determine whether the program succeeded, if you don't tell it. Somewhere deep in the bowels of the system is a call along the lines of
int returnstatus;
returnstatus = main(argc, argv);

If you use void main(), a number of interesting possibilities arise


  1. The program may work exactly as you expected. 
  2. The return status may end up with a trap representation, and crash the program (or the whole machine). 
  3. The startup code may send the spurious return code to the operating system, which then decides to roll back a database transaction because the program didn't return a success value. 
  4. Worst of all, the startup code may reach out to your nose and start extracting demons from it.

The main() function returns an int. There are exactly three portable values you can return from main(). They are:
0
EXIT_SUCCESS
EXIT_FAILURE

The last two are both defined in <stdlib.h>, and their actual values vary from system to system. If you return 0, the startup code will tell the operating system or other host environments that your program succeeded, translating the 0 into some other value if necessary.

Actually, main() can be defined in an implementation-defined way. Therefore, it's not necessarily illegal to define main as
int main(int argc)
or
int main(int argc, char **argv, char **env)

But you should be aware that no compiler is obliged to support either of these two definitions; they are only legal for compilers that document these alternative forms, which certainly only includes some compilers.

Here are the probable definitions of main


int main(void)
int main(int argc, char **argv)
int main(int argc, char *argv[])

Any definition is exactly equivalent to any one of the above Thus, you can use different variable names for argc and argv, you can use FOO if the definition is preceded by typedef int FOO, and so on. But to be portable, you must return int from main and you must take either no arguments or the two specified by the standard. If you need to access the environment in a portable way, you can of course use getenv().


Happy Exploring!

No comments:

Post a Comment