Must the Int Main() Function Return a Value in All Compilers

Must the int main() function return a value in all compilers?

In C++, and in C99 and C11, it is a special rule of the language that if the control flow reaches the end of the main function, then the function impliclty returns 0.

What should main() return in C and C++?

The return value for main indicates how the program exited. Normal exit is represented by a 0 return value from main. Abnormal exit is signaled by a non-zero return, but there is no standard for how non-zero codes are interpreted. As noted by others, void main() is prohibited by the C++ standard and should not be used. The valid C++ main signatures are:

int main()

and

int main(int argc, char* argv[])

which is equivalent to

int main(int argc, char** argv)

It is also worth noting that in C++, int main() can be left without a return-statement, at which point it defaults to returning 0. This is also true with a C99 program. Whether return 0; should be omitted or not is open to debate. The range of valid C program main signatures is much greater.

Efficiency is not an issue with the main function. It can only be entered and left once (marking the program's start and termination) according to the C++ standard. For C, re-entering main() is allowed, but should be avoided.

Is It Necessary to Return a Value in Main()?

The C99 standard says: (§5.1.2.2.1 Program startup)

The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent; or in some other implementation-defined manner.

So in a hosted environment, int is the only valid, standard return type. Implementations can define other entry points though.

Note that section §5.1.2.2.3 Program Termination has this:

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

So you omitting a return from main is legal in C99, as long as your main returns an int.

(But previous versions of the C standard didn't have that exception for main - returning no value (or reaching the final } without a return statement) causes "the termination status returned to the host environment [to be] undefined.".)

Why does the main function work with no return value?

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.

Does int main() need a declaration on C++?

A definition of a function is also a declaration of a function.

The purpose of a declaring a function is to make it known to the compiler. Declaring a function without defining it allows a function to be used in places where it is inconvenient to define it. For example:

  • If a function is used in a source file (A) other than the one it is defined in (B), we need to declare it in A (usually via a header that A includes, such as B.h).
  • If two or more functions may call each other, then we cannot define all those functions before the others—one of them has to be first. So declarations can be provided first, with definitions coming afterward.
  • Many people prefer to put “higher level” routines earlier in a source file and subroutines later. Since those “higher level” routines call various subroutines, the subroutines must be declared earlier.

In C++, a user program never calls main, so it never needs a declaration before the definition. (Note that you could provide one if you wished. There is nothing special about a declaration of main in this regard.) In C, a program can call main. In that case, it does require that a declaration be visible before the call.

Note that main does need to be known to the code that calls it. This is special code in what is typically called the C++ runtime startup code. The linker includes that code for you automatically when you are linking a C++ program with the appropriate linker options. Whatever language that code is written in, it has whatever declaration of main it needs in order to call it properly.

What happens if main() does not return an int value?

If main doesn't return int, then you have an ill-formed program and behavior is undefined. Anything can happen. Your program might crash, or it might run as though nothing were wrong at all.

Let's suppose main returned something other than int, and your compiler and linker allowed the program to be made. The caller doesn't know that, though. If the caller expects returned int values to be returned in the EAX (Intel) register, then that's what it will read to determine the return value of main. If your faulty main stored a float value there, then it will be interpreted as an int instead. (That doesn't mean it will get truncated. It means the bits making up the layout of a floating-point value will instead make up an int instead.) If your faulty main returned void, then it didn't store anything in the expected register, so the caller will get whatever value was previously stored in that register instead.

If your main returns some type that it expects to store someplace that the caller didn't' reserve memory for (such as a large struct), then it will end up overwriting something else, perhaps something important to the clean shutdown of the program, causing your program to crash.

The return type of main() function

The C standard (ISO/IEC 9899:2011) says:

5.1.2.2.1 Program startup


1 The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent;10) or in some other implementation-defined manner.

10) Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as
char **argv, and so on.

Thus, the only portable declaration for main() has a return type of int. If MSVC defines that void is permitted ('or in some other implementation-defined manner'), so be it, but do not expect the code to be portable. The old versions of the Microsoft compilers (up to and including MSVC 2005) do not permit void main(): see the documentation at main: Program startup and The main Function and Program Execution. However, MSVC 2008 and later are documented to allow void main(): see main: Program Startup. The three-argument form of main() is noted as a common extension in Appendix J:

J.5 Common extensions


The following extensions are widely used in many systems, but are not portable to all
implementations. The inclusion of any extension that may cause a strictly conforming
program to become invalid renders an implementation nonconforming. Examples of such
extensions are new keywords, extra library functions declared in standard headers, or
predefined macros with names that do not begin with an underscore.

J.5.1 Environment arguments


In a hosted environment, the main function receives a third argument, char *envp[],
that points to a null-terminated array of pointers to char, each of which points to a string
that provides information about the environment for this execution of the program
(5.1.2.2.1).


The value returned from main() is transmitted to the 'environment' in an implementation-defined way.

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.

11) In accordance with 6.2.4, the lifetimes of objects with automatic storage duration declared in main
will have ended in the former case, even where they would not have in the latter.

Note that 0 is mandated as 'success'. You can use EXIT_FAILURE and EXIT_SUCCESS from <stdlib.h> if you prefer, but 0 is well established, and so is 1. See also Exit codes greater than 255 — possible?.

7.22.4.4 The exit function


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

Function must return a value

The "unresolved externals" message isn't directly caused by your returning a value.

It's a linker error, and only occurs because compilation succeeded.

The cause is that you're declaring, and calling, this parameter-less function:

std::string CharacterCreation();

but you're defining this function with two parameters:

std::string CharacterCreation(int RaceChoice, int RaceChoiceLoop)

The declaration and the definition must match.

From the looks of it, you don't actually want the parameters and should use local variables instead:

std::string CharacterCreation()
{
int RaceChoice = 0;
int RaceChoiceLoop = 0;
// ...


Related Topics



Leave a reply



Submit