21

This question is out of curiosity; while writing a main for a test program, I returned nothing from main(no return statement in main). But I declared main as int main(). And it compiled successfully.

Where as if there is any other function written with a int return type and actually not returning an int,I would get an error

'Function name' must return value

So why compiler doesn't complain the same for main function?

byxor
  • 5,930
  • 4
  • 27
  • 44
ZoomIn
  • 1,237
  • 1
  • 17
  • 35
  • 2
    Check this answer: http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c – Alex1985 Oct 10 '13 at 10:47
  • yes @Alex1985,my question was why C++ allows main to compile with no return value even though we have specified return type – ZoomIn Oct 10 '13 at 10:58

2 Answers2

23

Normally it is not allowed for the control flow to reach the end of a non-void function without returning something. The main function is handled differently, as specified in the standard.

From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2960.pdf:

§ 3.6.1/5

If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;

As for the rationale, I'm not sure, honestly. If someone knows, please add it to my answer or as a comment.

Tamás Szelei
  • 23,169
  • 18
  • 105
  • 180
  • 2
    I looked it up. I believe this was introduced with C99, and apparently the C99 rationale is defect. It has comments for 5.1.2.2.1 Program startup, then labels the next chapter 5.1.2.3 Program execution. It should have been 5.1.2.2. As a consequence of this, the rationale for Program termination that should have been in the real chapter 5.1.2.3, has gone missing in action. Thus, main allows no return code in C99 _and there exists no rational reason why_. – Lundin Oct 10 '13 at 11:03
  • 1
    I can't think of no other rationale than that of maintaining compatibility with the corpus of C/C++ source codes that had existed prior to standardization. C was very lax in its early years. – ach Oct 10 '13 at 11:05
  • @Lundin that's excellent, thank you. I've been wondering about this for a long time myself. – Tamás Szelei Oct 10 '13 at 11:09
  • @Lundin If that's true,then I feel sad about it or if like Andrey mentioned it is for compatibility reasons then makes sense. – ZoomIn Oct 10 '13 at 11:16
  • The reason for it is **not** backward compatibility; this was a new idea introduced in C++98, and the idea was to make it easier to teach beginners by not having to write and explain `return 0;` in `main`. – Pete Becker Oct 10 '13 at 11:41
  • 3
    I actually looked up the C90 standard and the clause **was** there. Actually, the section 2.1.2 "Execution Environments" is pretty much the same as the section 5.1.2 "Execution Environments" of C99. And I am pretty sure that C++98 also did have that clause. So it was surely not in C99 that this rule was introduced. – ach Oct 10 '13 at 11:46
  • 2
    @ach: I know it's been a time, but... are you sure you had the right document? The ANSI/ISO 9899:1990 I have here has a section *2 Normative references*, which isn't what we're looking for, and section *5.1.2.2.3 Program termination* just like C99. And it states there that (emphasis mine) "if the main function executes a return that specifies no value, the termination status returned to the host environment is **undefined**". I guess they preferred a well-defined EXIT_SUCCESS over an undefined return state, which is good enough for me. But the "implicit `return 0;`" wasn't there in C89/90. – DevSolar Feb 12 '20 at 10:03
  • @DevSolar Now that more than 6 years have passed, I am not sure of anything... – ach Feb 12 '20 at 10:08
5

In C++, int main() can be left without a return value at which point it defaults to returning 0.

5.1.2.2.3 Program termination

1 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.

But you should be better of using EXIT_SUCCESS or EXIT_FAILURE for return from main().

Even though you're returning an int, some OSes (Windows) truncate the returned value to a single byte (0-255). Unix does the same, as do most other operating systems probably.Returning anything other than EXIT_SUCCESS or EXIT_FAILURE is asking for trouble

A Quote from GNU Library

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.

— Macro: int EXIT_SUCCESS This macro can be used with the exit function to indicate successful program completion.

On POSIX systems, the value of this macro is 0. On other systems, the value might be some other (possibly non-constant) integer expression.

— Macro: int EXIT_FAILURE This macro can be used with the exit function to indicate unsuccessful program completion in a general sense.

On POSIX systems, the value of this macro is 1. On other systems, the value might be some other (possibly non-constant) integer expression. Other nonzero status values also indicate failures. Certain programs use different nonzero status values to indicate particular kinds of "non-success". For example, diff uses status value 1 to mean that the files are different, and 2 or more to mean that there was difficulty in opening the files.

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112
  • 1
    _But you should be better of using EXIT_SUCCESS or EXIT_FAILURE for return from main()_ - Care to elaborate? – ComicSansMS Oct 10 '13 at 11:02
  • @ComicSansMS - Because it exists for a reason in `stdlib.h` – Rohit Vipin Mathews Oct 10 '13 at 11:24
  • @ComicSansMS - I have added the required explanations on the topic to my answer. – Rohit Vipin Mathews Oct 10 '13 at 11:31
  • 2
    Your quote (btw it would be nice if you could give a source for that) makes sense when considering returning an `int` literal versus returning one of the `EXIT_*`s. It does _not_ address the case of using the default return vs explicitly returning `EXIT_SUCCESS`. So I'm still not convinced :) – ComicSansMS Oct 10 '13 at 11:34
  • Default return in most cases return 0 or 1 (int) which could cause problems if the OS or calling process expects value different to it. SO for portability it is better to use platform independent value `EXIT_SUCCESS` or `EXIT_FAILURE` – Rohit Vipin Mathews Oct 10 '13 at 11:44
  • 6
    Did some digging into the standard: `return 0`, both implicitly and explicitly is equivalent to calling `exit(0)` (§3.6.1,5), which in turn is equivalent to calling `exit(EXIT_SUCCESS)` (§18.5 C++; §7.22 C). In both cases it is the responsibility of the compiler to ensure portability (ibid.), so it makes no difference at all whether you use `EXIT_SUCCESS` or `return 0` or omit the return completely. No such guarantees are given for non-zero return codes though, so there the use of `EXIT_FAILURE` might at least theoretically increase portability. – ComicSansMS Oct 10 '13 at 12:19
  • Alright!! I quit the argument! Anyways I still think `EXIT_SUCCESS` and `EXIT_FAILURE` as more stable cross platform. – Rohit Vipin Mathews Oct 11 '13 at 10:13