24

Possible Duplicate:
What is the proper declaration of main?

Without citing any code in particular, I am looking for an explanation of the below example:

#include <iostream>

int main()
{
    std::cout << "Hello world" << std::endl;
    return 0;
}

I don't understand what return 0 does. Can you please explain this in as plain English as possible?

Community
  • 1
  • 1
  • 2
    In plain English: The function `main` returns the value `0`. The C++ standard describes how this is to be interpreted by the host environment. – Kerrek SB Jan 02 '12 at 01:17
  • 1
    In the Unix shell, it allows you to tell whether the command succeeded or not, and maybe why it failed if it failed. If the exit status (value returned from `main()` or specified as the argument to `exit()`, `_exit()` or `_Exit()`) is zero, it will be interpreted as success by the calling environment (shell). If the value passed is `EXIT_FAILURE`, then it will be interpreted as a failure by the calling environment. Unix allows values 0..255 for exit statuses (though sometimes that is interpreted as -128..+127). You can pick up the actual value in `$?` in most shells. Signals complicate things. – Jonathan Leffler Jan 02 '12 at 01:24
  • Okay folks. Please correct me, but this is how I now understand it. return 0 is a statement that tells the operating system or observing application that the function or program executed successfully. Any other integer in place of the zero usually means an error. The return integer is not something that can be set by rules, if you will, but when it's set to zero, this means the application exited successfully. The integer should range from 0-255, and to check it on a Windows box, you'd run %ERRORLEVEL%. Is this correct? –  Jan 02 '12 at 04:35
  • Hardly... 0=success, anything else=ERROR. The actual value does not mean anything, except what the actual program wants it to mean. – Frunsi Jan 02 '12 at 04:37
  • 1
    The explanation: some process (A) on your computer starts another process (B). When B exits, it will always store a kind of "exit status" somewhere (which is what main returned, or what your program actually gave as a parameter to your `exit` function). The parent process (A) can read that value, and act relative to it: E.g.: a windows ".bat" script may read that %ERRORLEVEL% thing and act on it. A UNIX shell script may read that $? thing, and act on it. – Frunsi Jan 02 '12 at 05:09
  • Please don't roll back the edit that included questions that this question is closed as a duplicate of. If you think it's not a duplicate and shouldn't have been closed, please flag for moderator attention and we'll take a closer look. Thanks! – Adam Lear Jan 02 '12 at 07:27
  • 1
    While we're on the subject, http://stackoverflow.com/questions/3309042/what-does-main-return is an entirely different question. – johnsyweb Jan 02 '12 at 07:45

12 Answers12

42

This defines the exit status of the process. Despite being an int, on Unix-like systems, the value is always in the range 0-255 (see Exit and Exit Status). On Microsoft systems you may use 32-bit signed integers as exit codes, which you can check with %ERRORLEVEL%. For portability, I'd recommend sticking to the 0-255 range.

Here is a trivial example:

$ cat -n exit_code.cpp 
     1  int main()
     2  {
     3      return 42;
     4  }
     5  

Build:

$ make exit_code
g++ exit_code.cpp -o exit_code

Run (in bash):

$ ./exit_code

Check the exit status:

$ echo $?
42

Conventionally, a status of zero signifies success and non-zero failure. This can be useful in shell scripts, and so forth to indicate the level of failure, if any:

$ ./exit_code
exit_status=$?
if [[ ${exit_status} ]] ; then
    echo "The process failed with status ${exit_status}."
else
    echo "Success!"
fi
The process failed with status 42.

Following the comments below...

In the standard C++ header <cstdlib>, the following macros are defined:

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

However, the Exit Status section of the GNU C Library documentation, describing the same macros, sagely states:

Portability note: Some non-POSIX systems use different conventions for exit status values. For greater portability, you can use the macros EXIT_SUCCESS and EXIT_FAILURE for the conventional status value for success and failure, respectively. They are declared in the file stdlib.h.

Community
  • 1
  • 1
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
  • 1
    Thank you! But why would the coder define the error code? –  Jan 02 '12 at 01:19
  • Okay, but what's the issue with all the additional command line flags (on gcc) ?? – Frunsi Jan 02 '12 at 01:21
  • 3
    +1 for a nice clear answer :) As a side point for the OP, whilst 42 illustrates the point nicely here, I think I recall right in saying that the only portable return codes are 0, EXIT_SUCCESS and EXIT_FAILURE - so don't use other things if you want your code to be portable. – Stuart Golodetz Jan 02 '12 at 01:21
  • 1
    Also on a Windows system you can test the status by typing: echo %errorlevel% – David P Jan 02 '12 at 01:24
  • @frunsi: I was in the process of editing those out to make my answer clearer when you commented, they're the `${CXXFLAGS}` in my environment. – johnsyweb Jan 02 '12 at 01:27
  • Might be worth mentioning function return values in general; there's no evidence in the question that the OP knows the distinction between return values and specifically what `main`'s return value is used for. – Lightness Races in Orbit Jan 02 '12 at 01:30
  • @Johnsyweb: Alrighty :-) However, I'd also renounce on that EXIT_* rules. Because the actual standard-, invariant- (it doesn't matter which OS or hardware used) and after all non-changeable rule is: 0=success, not zero=failure. – Frunsi Jan 02 '12 at 01:35
  • 2
    @frunsi: Can you cite the standard for that rule please? – Lightness Races in Orbit Jan 02 '12 at 01:38
  • @frunsi: That a *standard* or a *convention*? ;-) – johnsyweb Jan 02 '12 at 01:40
  • @Johnsyweb: AFAIK, this is a Convention. Tomalak: If you can cite me the standard(s) which mentions those "EXIT_*" states, then I will tell you which standard(s) it is based on. However, I am sure, then you will not need my answer anyway. Right? If you feel affronted by now, then please relax, before the final conclusion... – Frunsi Jan 02 '12 at 01:50
  • I think my last paragraph sums it up nicely, then, with an example. If you think it could be clearer, please feel free to edit my answer, I shall not take offence ☻ – johnsyweb Jan 02 '12 at 01:53
  • @TomalakGeret'kal: So, after all, can we agree on that answer? – Frunsi Jan 02 '12 at 02:07
  • 1
    @frunsi: I didn't understand your penultimate comment. You indicated that you think the use of "0=success, !0=failure" is standardised: please indicate which standard makes this the case for C++, with a citation. – Lightness Races in Orbit Jan 02 '12 at 02:11
  • 2
    @Johnsyweb: True, but AFAIK those three are the three portable return codes mentioned in the ISO C++ standard. Sadly I don't have a reference for this offhand, although a quick Google for 'c++ portable return main exit_success' does seem to lend credence to what I'm trying to say. Also, useful and portable are not necessarily the same thing. – Stuart Golodetz Jan 02 '12 at 02:11
  • @Tomalak: 0 = success is standardised AFAIK by the ISO C++ standard. I'm basing this on discussions I've had in comp.lang.c++, but I don't have a copy of said standard to hand to cite, sorry. – Stuart Golodetz Jan 02 '12 at 02:13
  • 1
    Actually, I do have a reference from the draft standard (freely available) - see p.460 of http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf – Stuart Golodetz Jan 02 '12 at 02:20
  • 1
    See also p.62 of the same reference for the (crucial additional) fact that return from main calls std::exit. – Stuart Golodetz Jan 02 '12 at 02:26
  • 2
    Thanks for the commentary, folks. Hopefully with my updated post @DustinStalin has sufficient information to answer his question. – johnsyweb Jan 02 '12 at 02:45
  • 1
    Perhaps you'd be kind enough to take this discussion, which is no longer relevant to my answer, [elsewhere](http://chat.stackoverflow.com/)? – johnsyweb Jan 02 '12 at 03:55
  • 1
    @Johnsyweb & MooingDuck: Sorry for that. I removed all my comments, which were related to that unfavourable topic. – Frunsi Jan 02 '12 at 04:00
  • 1
    Please keep comments constructive and on topic. – Tim Post Jan 02 '12 at 04:10
  • Please don't feel offended... desides some appreciation discussions here, you really should supplement your answer with a note about the actually refered context. A "return value" is meaned in the context of the source code of a process ..., but when you mention an "%ERRORLEVEL%", then the context is some kind of batch scripting thing (no idea how that is called in WIN32). And so on... – Frunsi Jan 02 '12 at 05:38
  • @frunsi: No offence taken. Since the question has been closed, I'm going to leave the answer as is. FYI `%ERRORLEVEL%` is the MS equivalent of `$?`. Cheers! – johnsyweb Jan 02 '12 at 05:48
  • 1
    @StuartGolodetz: Ah, good find! Yes, it seems 3.6.1/5 and 18.5/8 standardise this behaviour. Thanks for finding it. – Lightness Races in Orbit Jan 02 '12 at 15:02
8

General returning

Every function has a return type.

In the below example, the type is void, which is an "incomplete type" with no values; using this as the return type means that the function returns no value:

void foo() {
   std::cout << "Hello world\n";
}

However, in the below example, the return type is int:

int foo() {
   return 3;
}

The return statement determines what value calls to function foo will evaluate to. So, std::cout << foo() will result in "3" being printed to standard output.


returning from main, specifically

When the function in question happens to be the "main" function, or the program's entrypoint, it's a bit more special, because the "return value" of the "main" function is taken to be the program's "exit code" — it tells the calling environment (e.g. terminal session) whether the program's execution was deemed to be successful. It must be an int, and a value of 0 here means "everything went fine":

It's worth noting that you can actually completely omit return 0; in the "main" function as it will be included implicitly. This doesn't help you much, though, if you want to return 1; or some other value, and it doesn't come into play with other functions.


Citations

[C++11: 3.6.1/5]: A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

[C++11: 18.5/8]:

       [[noreturn]] void exit(int status)

The function exit() has additional behavior in this International Standard:

  • First, objects with thread storage duration and associated with the current thread are destroyed.
    Next, objects with static storage duration are destroyed and functions registered by calling atexit are called. See 3.6.3 for the order of destructions and calls. (Automatic objects are not destroyed as a result of calling exit().)
    If control leaves a registered function called by exit because the function does not provide a handler for a thrown exception, terminate() shall be called (15.5.1).
  • Next, all open C streams (as mediated by the function signatures declared in <cstdio>) with unwritten buffered data are flushed, all open C streams are closed, and all files created by calling tmpfile() are removed.
  • Finally, control is returned to the host environment. If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

Bootnote

I suggest one of these resources, as this sort of thing is explained properly in any decent peer-reviewed C++ book; YouTube tutorials are not a good way to learn C++, and Stack Overflow contributors will generally expect you to have a decent book to form your prior research before resorting to asking for help.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • For a hosted program, there's nothing "conventional" -- the Standard describes pretty clearly what the return value of `main` is supposed to achieve... – Kerrek SB Jan 02 '12 at 01:26
  • @KerrekSB: Can't see that in 3.6.1; chapter and verse, please? – Lightness Races in Orbit Jan 02 '12 at 01:29
  • 3
    @TomalakGeret'kal: 18.5 "Finally, control is returned to the host environment. If status is zero or `EXIT_SUCCESS`, an implementation-defined form of the status successful termination is returned. If status is `EXIT_FAILURE`, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined." – Ben Voigt Jan 02 '12 at 02:41
  • Yes, a function may have a return type. And it may even not have a return type at all. – Frunsi Jan 02 '12 at 04:16
  • 1
    @frunsi: it always has a type, it might not always return a _value_. `void` is a type. – Mooing Duck Jan 02 '12 at 04:32
  • @MooingDuck: Yes, but we actually are not talking or arguaing about that. The question was about the return value of a "main" function, which results in a question about the return value of an actual program, e.g. an actual process... you know. WE DO NOT TALK ABOUT THE CONCEPT OF A RETURN VALUE OF A FUNCTION at all. – Frunsi Jan 02 '12 at 04:40
  • Thank you for the link and explanation, Tomalak! I learn better with video, and a lot of friends recommended people like The New Boston, but upon reading your answer, I will switch to books. Thanks again! –  Jan 02 '12 at 04:41
  • @TomalakGeret'kal: I didn't understand your penultimate comment. You indicated that you think the use of the concept that a function will return "something" is standardised: please indicate which standard makes this the case for C++, with a citation. – Tomalak Geret'kal 2 hours ago – Frunsi Jan 02 '12 at 04:56
  • PS: @MooingDuck: a return type void means "has no return type at all". We may want to argue about the details. But for the abstraction required here, we can safely assume, that a function does not have a return type at all (so, it may just be called a "procedure" in some mental models of programming, but we do not have to). So: what did you wanted to say after all? What? What? What? – Frunsi Jan 02 '12 at 05:23
  • PS: @MooingDuck: In conclusion: You are absolutely wrong. NO, `void` is the hypothetical type construct, representing a "no type", and in result, representing something that after all can not contain a value after all. After all, I do not even understand, why you had to write your comment? Just for having an opinion at all? – Frunsi Jan 02 '12 at 05:49
  • 1
    @frunsi: C++11 §3.9.1\9 "The void type has an empty set of values. The void type is an incomplete type that cannot be completed. It is used as the return type for functions that do not return a value." The C++ standard seems quite clear to me that `void` is indeed a type. I can see how it's easy to see "void" as a typeless construct, so the mistake is understandable. – Mooing Duck Jan 02 '12 at 07:20
  • So, using the hypothetical construct of a `void return type` represents the case, that function does not have a return type at all. Right? Of course, void is a type! But its meaning is to be a type, that actually represents no type. So what? – Frunsi Jan 02 '12 at 08:15
  • 1
    a function with a void return type represents a function with no return_value_. void does _not_ represent no type. It represents no _value_. – Mooing Duck Jan 02 '12 at 09:05
  • @frusni: I was looking for what @StuartGolodetz found, that C++11 3.6.1/5 and 18.5/8 standardise the use of zero and `EXIT_SUCCESS` for success; note though that "non-zero for failure" is implementation-defined; only `EXIT_FAILURE` for failure is well-defined. _[edit: seems @BenVoigt found it too :D]_ – Lightness Races in Orbit Jan 02 '12 at 15:04
  • @frusni: Also, @MooingDuck is completely correct; there is no need to be rude and agitated with him in any case. ` – Lightness Races in Orbit Jan 02 '12 at 15:05
  • I've added the citations into my answer. – Lightness Races in Orbit Jan 02 '12 at 15:11
1

It's used because you may use your program as a command line tool. If there is another process waiting for the output of your program you may choose to return 0 if everything is successful, -1 if there was an error or any other constant, according to what you want to communicate.

Manlio
  • 10,768
  • 9
  • 50
  • 79
1

Think of your boss telling you to go pick up the mail. After you pick up the mail, you tell your boss that everything went okay.

The operating system is the boss, the program is you. And all return 0 does is tells the operating system that everything went okay.

David Titarenco
  • 32,662
  • 13
  • 66
  • 111
1

Under windows you can test for return value as follows (in batch script):

MyAppTest.exe
@if "%ERRORLEVEL%" == "0" goto success
 echo Failure
 goto end
:success
 echo Success
:end
marcinj
  • 48,511
  • 9
  • 79
  • 100
1

Returning from main() has the same effect as calling std::exit() and passing the return value as the status parameter.

The behavior of std::exit is detailed in section 18.5 ([support.start.term]), and describes the status code:

Finally, control is returned to the host environment. If status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
0

return is used to escape the function. Returning the value 0 simply allows it to exit with a code: 0. Also, returning with 0 claims a successful exit of the application.

Serodis
  • 2,092
  • 4
  • 25
  • 34
0

0 is an integer.

Your main function has to return an integer.

Just look at:

int main()

int stands for integer and return in this case, returns 0: an integer to terminate the program.

Usually for an error you have to return 1; 0 is the conventional value for success.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
user1056635
  • 785
  • 2
  • 9
  • 12
0

Depends on operating system, but an exit code of 0 means success on UNIX, VMS and Windows

P Varga
  • 19,174
  • 12
  • 70
  • 108
0

The return value from the main function is returned to the calling application or process (a lot of times this is a shell script). The return value is used to signal the exit status of the application.

There are no hardened rules at to what the return value should be but, by convention a return value of zero signifies normal application exit. Any non-zero value signifies abnormal application exit.

Brent Worden
  • 10,624
  • 7
  • 52
  • 57
0

In simple applications like yours the returned value means nothing. If there is an observing process (like if one program launches another) it can be an easy way to get communicate a status or error code.

For a simple application which does not have an status or error codes, most people return 0 for a normal application exit (usually success) and return 1 if the app. fails to properly execute.

Don Scott
  • 3,179
  • 1
  • 26
  • 40
0

On a modern operating system, every program will exit with a specific "exit code".

DISCLAIMER NO 1.: The actual specification of that concept (of having an exit code at all) is out of the scope of any programming language specification at all. So: ANYONE asking me again about a reference to a standard may please retreat into itself, and think about a better answer for the moment.

DISPLAIMER NO 2.: The actual values of those exit codes are not specified in not actual "programming language specification", because that is out of the scope of a "programming language specification".

So long, practice has shown, that an exit code of "0" means "success", and any other code signals an error...

Frunsi
  • 7,099
  • 5
  • 36
  • 42