views:

129

answers:

6

I know it's been the convention in ANSI C to always return a 0 integer value from main in a C program, like this:

int main() {

    /* do something useful here */

    return 0;
}

This is to return a "successful" result to the operating system. I still consider myself a novice (or an intermediate programmer at best) in C, but to date I've never fully understood why this is important.

My guess is, this is a useful return result if you're tying the output of this program into the input of another, but I'm not sure. I've never found it useful, or maybe I just don't understand what the intention is.

My questions:

  1. Is returning zero always necessary from a C program?
  2. How is the return value from main() useful?
+5  A: 

Hello. When writing scripts (like in Bash, or CMD.exe on Windows) you can chain some commands with the && and || operators.

Canonically, a && b will run b if the result of a is zero, and a || b will run b if a returned nonzero.

This is useful if you wish to conditionally run a command if the previous one succeeded. For example, you would like to delete a file if it contains word foo. Then you will use :

grep foo myfile && rm myfile

grep returns 0 when there was a match, else nonzero.

Benoit
How is this helpful?
Alexander Rafferty
I think your answer is useful, but it's not very clear. Can you give me an example? It looks like you cut and pasted some text from a goggle search...
dvanaria
No, I didn't cut and past, but I am no native English speaker, hence it can puzzle some readers sometimes.
Benoit
Well fair enough, I think he is explaining that the return value can be useful for conditions.
Alexander Rafferty
+1  A: 

The return value is the "result" of the program execution, and 0 is used to indicate a successful termination, while a non-zero return value indicates a failure or unexpected termination.

The return value doesn't really matter to the system when you call you program normally, but it can have two purposes. One of them is debugging. In MSVC, the most commonly used compiler for C++, you see the programs return value after it finishes executing. This can be helpful to see "how and why" your program exited.

Another use is when your application is called from other programs, where the return value may indicate success, or pass on a result.

Alexander Rafferty
A: 

Hiya, like you said its mainly if the program is used as part of wider program network. Returning zero to the program environment lets the network know everything went fine (like you said) however you can also have it return 1, 2, 3... (depending on what error has occured) to let your network of code know that something has gone wrong. Equivalently, you can have exit(0) or exit(1) at the end of your 'main' program to do exactly the same thing. You may find this useful: http://en.wikipedia.org/wiki/Exit_status Hope that helps. Jack

Jack Medley
+1  A: 

In modern C aka C99 (not sure for C89) all the three terminations of main are equivalent:

  • just ending main at the last }
  • return 0
  • exit(0)

the idea behind all this is (as others mentioned) to give a return status to the invoking program.

Jens Gustedt
The first one is incorrect. Barring an explicit `return`, a C function will return the last thing it evaluated. `int main() { printf("Hello, world!\n"); }` will actually exit with `14` because the `printf()` returned it. (If you've got compiler warnings turned on as you should, compiling this will squawk about control reaching the end of a non-void function.) The second is correct only in `main()`.
Blrfl
The first one *is* correct in C99 (but not in C89): "If the return type of the main function is a type compatible with int, [...] reaching the } that terminates the main function returns a value of 0." (C99 5.1.2.2.3)
schot
A: 

You should use EXIT_SUCCESS when the program finished correctly, and EXIT_FAILURE when it didn't. EXIT_SUCCESS is zero, and zero is portable to any operating system, while EXIT_FAILURE changes from UNIX to Windows, for example. These constants are defined in the stdlib header.

#include <stdlib.h>

int main()
{

    int toret = EXIT_SUCCESS;

    if ( !( /* do something useful here */ ) ) {
        toret = EXIT_FAILURE;
    }

    return toret;
}

The return code of the program was more useful when programs were written for the console. Nowadays, it is quite uncommon, unless you work in a very professional environment (and even this is now changing, with the workflow tools available).

As @Benoit said, the exit code tells the operating system when the operation was successful or not. If the exit code means failure, then you can break the flow of the batch program, since it is not likely to work out.

For example, a compiler can have an exit code of zero if compilation was successful, and any another value if compilation was unsuccesful. In Windows, this can be accessed through the operating system variable "errorlevel":

gcc helloworld.cpp -ohelloworld.exe
goto answer%errorlevel%
:answer0
copy helloworld.exe c:\users\username\Desktop
echo Program installed
goto end
:answer1
echo There were errors. Check your source code.
:end
echo Now exiting...

This windows batch file "installs" helloworld.exe in the Desktop when the compilation was successful. Since you can trigger execution of batch files with double-click, this can make it possible for you to avoid touching the command line for compilation.

Of course, take into account that is better managed by integrated environments (if the exit code did not exist, they wouldn't be able to work correctly). Also note that make is best in this field:

http://en.wikipedia.org/wiki/Make_(software)

Make also needs of exit codes to run correctly.

Baltasarq
The correct include file for C is "stdlib.h" and not "cstdlib.h"
Jens Gustedt
Thanks for pointing this clumsy error out.
Baltasarq
I find your claim that exit codes are "quite uncommon" quite bizarre. There are certainly many areas where they are no longer widely used, but these are the same areas where C itself is no longer widely used. In most cases, if you are using C, it is fairly likely that you will also care about exit codes.
Porculus
@Porculus, what I try to transmit (and I think I made it clear) is that it is not common among standard users, but among power users.
Baltasarq
+1  A: 

Returning 0 is a convention. When a program returns 0, it can be assumed that it worked OK, without actually looking at what the program did (ahem :D).

As a widely used convention, that assumption is in a lot of places. As Benoit points out that's the case of the shell (UNIX and Windows) and other parts of the Operating system.

So answering your questions:

  1. For a C program you must return either EXIT_SUCCESS or EXIT_FAILURE. But you can return EXIT_FAILURE even if your program worked OK.
  2. If you don't return a 0 (EXIT_SUCCESS), it's quite possible that other programs will assume your program failed.

There's a related question with C++ and C great responses

http://stackoverflow.com/questions/204476/what-should-main-return-in-c-c

Gonzalo