In C, the Section 5.1.2.2.1 of the C11 standard (emphasis mine):
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
andargv
, though any names may be used, as they are local to the function in which they are declared):int main(int argc, char *argv[]) { /* ... */ }
However for some beginners like me, an abstract example would allow me to get a grasp on it:
When you write a method in your program, e.g. int read_file(char filename[LEN]);
, then you want, as the caller of this method to know if everything went well (because failures can happen, e.g. file could not be found). By checking the return value of the method you can know if everything went well or not, it's a mechanism for the method to signal you about its successful execution (or not), and let the caller (you, e.g. in your main method) decide how to handle an unexpected failure.
So now imagine I write a C program for a micro-mechanism which is used in a more complex system. When the system calls the micro-mechanism, it wants to know if everything went as expected, so that it can handle any potential error. If the C program's main method would return void, then how would the calling-system know about the execution of its subsystem (the micro-mechanism)? It cannot, that's why main() returns int, in order to communicate to its caller a successful (or not) execution.
In other words:
The rational is that the host environment (i.e. Operating System (OS)) needs to know if the program finished correctly. Without an int-compatible type as a return type (eg. void), the "status returned to the host environment is unspecified" (i.e. undefined behavior on most OS).