1

I know the difference between return and exit() (link), but I don't know where and when to choose one instead of the other. For example from this answer I understand that return is a better choise, but from another I understand the opposite.

An example: in this code (from this question) is it preferable to use exit() or return?

int read_file (char *filename, int **vet)
{
    FILE *fin;

    if ( !(fin = fopen(filename, "r")) )
    {
        perror(filename);
        return -1;
    }

    * vet = malloc (10 * sizeof(int));
    if ( *vet == NULL )
    {
        perror("Memory allocation error.\n");
        return -2;   
    }

    /* ... */

    return fclose(fin);
}

int main ()
{
    char filename[100];
    int *vet;

    if ( read_file(filename, &vet) )
        /* ??? exit(1) OR return -1 ??? */

    return 0;
}

And generally?

Community
  • 1
  • 1
ᴜsᴇʀ
  • 1,109
  • 2
  • 9
  • 23
  • You wrote `exit(1) OR return -1 ???` -- `1` and `-1` are not equivalent. – Keith Thompson Jan 21 '14 at 22:26
  • 2
    @MikeW I had linked the same question in mine: it is different. – ᴜsᴇʀ Jan 21 '14 at 23:03
  • @user It is not different. There is a comprehensive explanation of the differences in that question. There is no right answer - it depends on what you are doing. In that context, your question has little meaning. –  Jan 21 '14 at 23:10
  • 1
    @user: No, not at all. The status value returned by the program should be exactly the same, whether it's returned via calling `exit` or executing a `return` statement. There's a convention of using negative values for error returns for some functions, but that does not apply to `main`. The only *portable* status values are `0`, `EXIT_SUCCESS`, and `EXIT_FAILURE`. (And on Unix-like systems, negative values are mapped to the range 0..255 anyway, so `return -1;` might be equivalent to `return 255;`.) – Keith Thompson Jan 21 '14 at 23:10
  • @KeithThompson Yes, sorry: I wrote my comment before reading your response! – ᴜsᴇʀ Jan 21 '14 at 23:13
  • @KeithThompson: "The status value returned by the program should be exactly the same, whether it's returned via calling exit or executing a return statement." That's not strictly true. See my answer on the original question. – Adrian McCarthy Aug 26 '15 at 23:28
  • @AdrianMcCarthy: Actually I believe it is strictly true, at least for conforming compilers. See my comment on [your answer](http://stackoverflow.com/a/27301635/827263) for details. – Keith Thompson Aug 26 '15 at 23:47
  • @KeithThompson: You're right. The standard requires this to be strictly true, but it puts some implementations into a no-win situation, so they don't strictly adhere to the standard in this regard. – Adrian McCarthy Aug 27 '15 at 16:36

3 Answers3

5

From within the main function, exit(N) and return N; are very nearly identical (but see below).

exit() terminates the entire execution of the program. return merely returns from the current function. (I know you said you know the difference, but I want to be complete).

If you're in main, you can use either one you like. The choice is a matter of style, and I don't think there's any agreement on what style is the best. You might consider using exit in case the code in main is later moved into some other function. I'd use return from main for more normal program termination.

Note that the value either passed to exit or used by return has a somewhat system-specific meaning. The value is returned to the calling environment. 0 or EXIT_SUCCESS denotes success; EXIT_FAILURE denotes failure. (EXIT_SUCCESS and EXIT_FAILURE are macros defined in <stdlib.h>, the same header that defines the exit function).

Any other value will have a system-specific meaning. In particular, there have been systems (VMS in particular) on which exit(1) indicates success, not failure. On a Unix-like system, where 1 denotes failure, EXIT_FAILURE will be defined as 1.

You can use EXIT_SUCCESS and EXIT_FAILURE with either return or exit().

On the other hand, if you need to specify more than one kind of failure, EXIT_FAILURE won't be enough. On Unix-like systems, and probably on Windows, 0 denotes success, 1 denotes a more or less generic failure, and other small positive integers denote other kinds of failure. Feel free to use specific values if that's what you need; you probably don't care that your program may not work as expected on VMS. (I'd define constants for the various exit values you use, and clearly say what they all mean in the documentation.) Again, you can use either exit() or return, whichever is more convenient.

I said above that exit(N) and return N from main() are almost identical.

It's legal in C for main to call itself recursively. If your program is in main, but not in the initial invocation of main, then return will terminate the current execution of main, but will not terminate the program; it's just like return vs. exit() for any function other than main. Calling main recursively is almost always a bad idea, so this is worth being aware of, but not worth worrying about.

Also, atexit() can be used to register functions to be called automatically on program exit. Any such functions will be called whether the function terminates due to exit() or return. The difference (and it's an incredibly obscure one) is that exit() is called by main, and return immediately leaves main. So if one of your atexit()-registered functions refers to a local variable inside main, that variable will still exist if you called exit(), but not if you executed a return statement. You would have to go out of your way to make this happen, and there's no good reason to do so, so you almost certainly don't have to worry about this particular issue.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 1
    And if I wanted to differentiate errors? For example: how can I wrote a code like `exit(1)`, `exit(2)`, etc. with `EXIT_FAILURE`? – ᴜsᴇʀ Jan 21 '14 at 23:19
  • 2
    @user: You can't do that in an *entirely* portable manner. But for most systems (certainly including Linux and other Unix-like systems, and probably including Windows as well), `exit(1)` denotes a more or less generic failure, and 2 or higher denotes some more specific error (e.g., `grep` uses 0 for a match, 1 for no match, and 2 for an error such as a missing file). `EXIT_FAILURE` is probably equal to 1, but if you need specific numeric values, just write `exit(1)`, `exit(2)`, etc. (or `return 1`, `return 2`). I've updated my answer; see the 7th paragraph. – Keith Thompson Jan 21 '14 at 23:40
  • +1 for the `atexit` paragraph. I had never considered that difference in behaviour before. – Stefano Sanfilippo Jan 22 '14 at 17:50
1

If used in the main, both will do the same, so I would choose return 1 because it's simpler and works without any #include.

exit is handy when you want to terminate from a function or otherwise outside your main routine.

Stefano Sanfilippo
  • 32,265
  • 7
  • 79
  • 80
  • Yes, but the meaning of `return 1;` is system-specific. (On Unix, it denotes success; on VMS, it denotes failure). `return EXIT_FAILURE;` is more reliable and clearer, but it requires `#include `. – Keith Thompson Jan 21 '14 at 22:25
  • @KeithThompson I completely agree with that. Only, the question was focused on `exit(1)` as opposed to `return 1`, so my answer is. – Stefano Sanfilippo Jan 22 '14 at 17:46
0

Its your choice.

The standard C library start-up code may well look like:

exit(main(argc,argv))

Returning from main probably calls exit anyhow. My personal choice would be to return the exit code from main as it does not disguise the flow of the code.

TheSavage
  • 269
  • 1
  • 10