Should I use exit()
or just return
statements in main()
? Personally I favor the return
statements because I feel it's like reading any other function and the flow control when I'm reading the code is smooth (in my opinion). And even if I want to refactor the main()
function, having return
seems like a better choice than exit()
.
Does exit()
do anything special that return
doesn't?
Another difference:
exit
is a Standard Library function so you need to include headers and link with the standard library. To illustrate (in C++), this is a valid program:but to use
exit
you'll need an include:Plus this adds an additional assumption: that calling
exit
frommain
has the same side effects as returning zero. As others have pointed out, this depends on what kind of executable you're building (i.e., who's callingmain
). Are you coding an app that uses the C-runtime? A Maya plugin? A Windows service? A driver? Each case will require research to see ifexit
is equivalent toreturn
. IMHO usingexit
when you really meanreturn
just makes the code more confusing. OTOH, if you really do meanexit
, then by all means use it.I always use
return
because the standard prototype formain()
says that it does return anint
.That said, some versions of the standards give
main
special treatment and assume that it returns 0 if there's no explicitreturn
statement. Given the following code:G++ only generates a warning for
foo()
and ignores the missing return frommain
:I STRONGLY second the comment by R. about using exit() in order to avoid having automatic storage in
main()
reclaimed before the program actually ends. Areturn X;
statement inmain()
is not precisely equivalent to a call toexit(X);
, since the dynamic storage ofmain()
vanishes whenmain()
returns, but it it does not vanish if a call toexit()
is made instead.Furthermore, in C or any C-like language a
return
statement strongly hints to the reader that execution will continue in the calling function, and while this continuation of execution is usually technically true if you count the C startup routine which called yourmain()
function, it's not exactly what you mean when you mean to end the process.After all, if you want to end your program from within any other function except
main()
you must callexit()
. Doing so consistently inmain()
as well makes your code much more readable, and it also makes it much easier for anyone to re-factor your code; i.e. code copied frommain()
to some other function won't misbehave because of accidentalreturn
statements that should have beenexit()
calls.So, combining all of these points together the conclusion is that it's a bad habit, at least for C, to use a
return
statement to end the program inmain()
.There is at least one reason to prefer
exit
: If any of youratexit
handlers refer to automatic-storage-duration data inmain
, or if you usedsetvbuf
orsetbuf
to assign to one of the standard streams an automatic-storage-duration buffer inmain
, then returning frommain
produces undefined behavior, but callingexit
is valid.Another potential usage (usually reserved for toy programs, however) is to exit from a program with recursive invocations of
main
.Actually, there is a difference, but it's subtle. It has more implications for C++, but the differences are important.
When I call
return
inmain()
, destructors will be called for my locally scoped objects. If I callexit()
, no destructor will be called for my locally scoped objects! Re-read that.exit()
does not return. That means that once I call it, there are "no backsies." Any objects that you've created in that function will not be destroyed. Often this has no implications, but sometimes it does, like closing files (surely you want all your data flushed to disk?).Note that
static
objects will be cleaned up even if you callexit()
. Finally note, that if you useabort()
, no objects will be destroyed. That is, no global objects, no static objects and no local objects will have their destructors called.Proceed with caution when favoring exit over return.
http://groups.google.com/group/gnu.gcc.help/msg/8348c50030cfd15a
With some compilers for uncommon platforms,
exit()
might translate its argument into your program's exit value while a return frommain()
might just pass the value directly to the host environment without any translation.The standard requires identical behavior in these cases (specifically, it says returning something that's
int
-compatible frommain()
should be equivalent to callingexit()
with that value). The problem is that different OSes have different conventions for interpreting the exit values. On many (MANY!) systems, 0 means success and anything else is a failure. But on, say, VMS, odd values mean success and even ones mean failure. If you returned 0 frommain()
, a VMS user would see a nasty message about an access violation. There wasn't actually an access violation--that was simply the standard message associated with failure code 0.Then ANSI came along and blessed
EXIT_SUCCESS
andEXIT_FAILURE
as arguments you could pass toexit()
. The standard also says thatexit(0)
should behave identically toexit(EXIT_SUCCESS)
, so most implementations defineEXIT_SUCCESS
to0
.The standard, therefore, puts you in a bind on VMS, as it leaves no standard way to return a failure code that happens to have the value 0.
The early-1990s era VAX/VMS C compiler therefore did not interpret the return value from
main()
, it simply returned whatever value to the host environment. But if you usedexit()
it would do what the standard required: translateEXIT_SUCCESS
(or0
) into a success code andEXIT_FAILURE
into a generic failure code. To useEXIT_SUCCESS
, you had to pass it toexit()
, you could not return it frommain()
. I don't know whether more modern versions of that compiler preserved that behavior.A portable C program used to look like this:
Aside: If I recall correctly, the VMS convention for exit values is more nuanced than odd/even. It actually uses something like the low three bits to encode a severity level. Generally speaking, however, the odd severity levels indicated success or miscellaneous information and the even ones indicated errors.