Why does the main function work with no return value?
Asked Answered
A

2

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?

Anking answered 10/10, 2013 at 10:45 Comment(2)
Check this answer: #204976Iridosmine
yes @Alex1985,my question was why C++ allows main to compile with no return value even though we have specified return typeAnking
X
24

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.

Xanthus answered 10/10, 2013 at 10:46 Comment(10)
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.Oleander
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.Sannyasi
@Oleander that's excellent, thank you. I've been wondering about this for a long time myself.Bulldog
@Oleander If that's true,then I feel sad about it or if like Andrey mentioned it is for compatibility reasons then makes sense.Anking
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.Maggot
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.Sannyasi
@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.Shipper
@Shipper Now that more than 6 years have passed, I am not sure of anything...Sannyasi
This was introduced in C++98. They probably thought that this makes C++ a "better C" in one more regard: C code ported to C++ will have one less bug. C99 then followed probably as a matter of compatibility with C++.Explore
You cannot underestimate the vast amount of ignorance out there about details like the concept of termination status. Large numbers of programs use void main, and those that use int main don't bother returning anything. On some platforms, termination status means little, like Microsoft Windows. A program launched from Explorer, terminated by the user closing its window, might have a termination status at the Win32 API level, but nothing cares about it.Explore
P
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.

Pili answered 10/10, 2013 at 10:55 Comment(7)
But you should be better of using EXIT_SUCCESS or EXIT_FAILURE for return from main() - Care to elaborate?Bourse
@Bourse - Because it exists for a reason in stdlib.hPili
@Bourse - I have added the required explanations on the topic to my answer.Pili
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 :)Bourse
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_FAILUREPili
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.Bourse
Alright!! I quit the argument! Anyways I still think EXIT_SUCCESS and EXIT_FAILURE as more stable cross platform.Pili

© 2022 - 2024 — McMap. All rights reserved.