In many languages such as C, C++, and Java, the main
method/function has a return type of void
or int
, but not double
or String
. What might be the reasons behind that?
I know a little bit that we can’t do that because main
is called by runtime library and it expects some syntax like int main()
or int main(int,char**)
so we have to stick to that.
So my question is: why does main
have the type signature that it has, and not a different one?
7
The return value of main
is to be passed to the operating system (any operating system) in a single, consistent way. The information that the operating system needs to know is “did the program terminate successfully, or was there an error?”
If this is a string, the response becomes difficult in different languages. The internals of a Pascal string (first byte is length) and a FORTRAN string (fixed, padded to some value) and a C string (null terminated) are all different. This would make returning a consistent value to the operating system challenging. Assuming that this was solved, what would you do to answer the question the OS had of the program? String comparisons are fraught with errors (“success” vs “Success”), and while the error may be more useful to a human, it is more difficult for the operating system or another program (shell) to deal with. There also were significant differences even in the strings themselves — EBCDIC (with all of its code pages) vs. ASCII.
Floats and doubles provide no additional value over the integer for communicating back data to the OS (and shell). For the most part, neither of these parts of the computer deal with floating point numbers. Doubles are also not enumerable making comparisons difficult. Not being enumerable, they make reporting what the error was (assuming you have picked a particular value for success). Again, floating points are not consistent – a float on an 8 bit machine was different than the float on a 16 bit and a 32 bit machine (and those are just the ‘normal’ ones – even within IBM, floating point wasn’t standardized between machines by the same manufacturer until the 1980’s). And then you’ve got decimal vs. binary computers. Floating point values aren’t consistent and don’t provide meaningful data back.
That really leaves us with the byte and integer as options. The convention that was established was ‘0’ was success, and anything else was an error. An integer gives more room than a byte for reporting the error. It can be enumerated (return of 1 means XYZ, return of 2 means ABC, return of 3, means DEF, etc..) or used as flags (0x0001
means this failed, 0x0002
means that failed, 0x0003
means both this and that failed). Limiting this to just a byte could easily run out of flags (only 8), so the decision was probably to use an integer.
7
Well, it could.
For example, in the dialect of C used in the Plan 9 operating system main
is normally declared as a void
function, but the exit status is returned to the calling environment by passing a string pointer to the exits()
function. The empty string denotes success, and any non-empty string denotes some kind of failure. This could have been implemented by having main
return a char*
result.
And it would certainly be possible to implement a system with a float
or double
exit status.
So why int
? It’s just a matter of convention — and there’s a tremendous value in having operating systems and programs that run under them obey a common convention.
The Unix convention is to use an integer status code, with 0 denoting success and non-zero denoting failure (because typically there’s only one way to succeed, but multiple ways to fail). I don’t know whether that convention originated with Unix; I suspect it came from earlier operating systems.
Floating-point would be a more difficult convention, because (a) floating-point support is not universal, (b) it’s more difficult to define a mapping between floating-point values and error conditions, (c) different systems use different floating-point representations, and (d) just imagine the fun of tracking down a rounding error in your program’s exit status. Integers, on the other hand, lend themselves very well to enumerating error codes.
Plan 9, as I mentioned, uses strings, but that imposes some complexity for memory management, character encoding, etc. It was, as far as I know, a new idea when Plan 9 implemented it, and it didn’t replace the existing widespread convention.
(Incidentally, in C++ main
can only return int
, and in C void main
is permitted only if the compiler specifically supports it. Many compilers don’t complain very loudly if you write void main
, but it’s only a slight exaggeration to say that it’s wrong.)
0
The value returned by the main method is an “exit code”. It’s used by the caller application (normally bash) to test if the program ended as expected. Returning an integer is the easiest way to do it on the OS level. Double makes no sense for error code and a String is hard to maintain in OS level (there is no GC).
2
main should return the status of the program which is executed.wether it is executed successfully(return 0 that is EXIT_SUCCESS) or not(return 1 means EXIT_FAILURE)
any non zero number conveys the same meaning but zero indicates no errors or successful execution..
1