What was the rationale for making `return 0` at the end of `main` optional?
Starting with the C99 standard, the compiler is required to generate the equivalent of a return 0
or return EXIT_SUCCESS
if no return is supplied at the end of main
. There was also a corresponding and identical change to the C++ language standard around that same time. I am interested in the reasons for both and I guessed that it was unlikely they were entirely separate and unrelated changes.
My question is:
What was the documented rationale for this change?
An ideal answer would cite authoritative sources for both C and C++ which is why I have tagged the question with both languages.
Note that unlike the question What the reasons for/against returning 0 from main in ISO C++?, I'm not asking for advice on whether to write return 0
in my programs -- I'm asking why the language standards themselves were changed.
To help understand the purpose for the question, here is a bit more of the context:
I've studied the standards searching for the answer myself before I asked here, but did not find the answer. I've been asked to help write coding standards for both languages for a group of programmers and I wanted to make sure I understand why this feature exists so that I may accurately explain its use to others.
In The New C Standard section 5.1.2.2.3 Program termination the author Derek Jones commentary on this lines from the C99 standard:
reaching the } that terminates the main function returns a value of 0
is:
The standard finally having to bow to sloppy existing practices.
Which indicates the rationale was to address poor programming practices with respect to explicitly returning a value from main
. Prior to this the status returned was undefined.
He indicates that many implementations already implemented this even in C90, so the fact that this change already reflected common implementation also probably helped.
The official rationale document for C99 scarcely addresses this. It appears that exit(0)
became the default for control flow off the end of main because exit(0)
was given meaningful portable semantics.
Here are the two relevant sections:
5.1.2.2.1 Program startup
The behavior of the arguments to main
, and of the interaction of exit
, main
and atexit
(see §7.20.4.2) has been codified to curb some unwanted variety in the representation of argv
strings, and in the meaning of values returned by main
.
The specification of argc
and argv
as arguments to main recognizes extensive prior practice.
argv[argc]
is required to be a null pointer to provide a redundant check for the end of the list, also on the basis of common practice.
main
is the only function that may portably be declared either with zero or two arguments. (The number of other functions' arguments must match exactly between invocation and definition.) This special case simply recognizes the widespread practice of leaving off the arguments to main
when the program does not access the program argument strings. While many implementations support more than two arguments to main
, such practice is neither blessed nor forbidden by the Standard; a program that defines main with three arguments is not strictly conforming (see §J.5.1.).
Command line I/O redirection is not mandated by the Standard, as this was deemed to be a feature of the underlying operating system rather than the C language.
and
7.20.4.3 The exit function
The argument to exit
is a status indication returned to the invoking environment. In the UNIX operating system, a value of zero is the successful return code from a program. As usage of C has spread beyond UNIX, exit(0)
has often been retained as an idiom indicating successful termination , even on operating systems with different systems of return codes. This usage is thus recognized as standard. There has never been a portable way of indicating a non-successful termination, since the arguments to exit
are implementation-defined. The EXIT_FAILURE
macro was added to C89 to provide such a capability. EXIT_SUCCESS
was added as well.
Aside from calls explicitly coded by a programmer, exit
is invoked on return from main
. Thus in at least this case, the body of exit
cannot assume the existence of any objects with automatic storage duration except those declared in exit
.
The Committee considered the addition of _exit
, but rejected it based on concerns of incompatible with the POSIX specification upon which it is based. For example, one concern expressed is that _exit
was specified as a way to get out of a signal handler without triggering another signal, but that is not actually the way _exit
behaves in POSIX environments. The Committee did not wish to give programmers this kind of false hope. (But see §7.20.4.4 for C99.)
上一篇: 调用具有错误签名的main()函数