return statement vs exit() in main()

Viewed 83414

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?

8 Answers

Actually, there is a difference, but it's subtle. It has more implications for C++, but the differences are important.

When I call return in main(), destructors will be called for my locally scoped objects. If I call exit(), 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 call exit(). Finally note, that if you use abort(), 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

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:

int main() { return 0; }

but to use exit you'll need an include:

#include <stdlib.h>
int main() { exit(EXIT_SUCCESS); }

Plus this adds an additional assumption: that calling exit from main 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 calling main). 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 if exit is equivalent to return. IMHO using exit when you really mean return just makes the code more confusing. OTOH, if you really do mean exit, then by all means use it.

I always use return because the standard prototype for main() says that it does return an int.

That said, some versions of the standards give main special treatment and assume that it returns 0 if there's no explicit return statement. Given the following code:

int foo() {}
int main(int argc, char *argv[]) {}

G++ only generates a warning for foo() and ignores the missing return from main:

% g++ -Wall -c foo.cc
foo.cc: In function ‘int foo()’:
foo.cc:1: warning: control reaches end of non-void function

In C returning from main is exactly the same as calling exit with the same value.

Section 5.1.2.2.3 of the C standard states:

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; 11) 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.

The rules for C++ are a bit different as mentioned in other answers.

There actually IS a difference between exit(0) and return(0) in main – when your main function is called multiple times.

The following program

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc == 0)
    return(0);
  printf("%d", main(argc - 1, argv));
}

Run as

./program 0 0 0 0

Will result in following output:

00000

However this one:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc == 0)
    exit(0);
  printf("%d", main(argc - 1, argv));
}

Won't print anything regardless of the arguments.

If you are sure that nobody will ever call your main explicitly it is not technically a big difference in general, but to maintain clearer code exit would look much better. If you for some reason want to call main – you should adjust it to your needs.

Speaking about C.

Related