What Is the Proper Declaration of Main in C++

What is the proper declaration of main in C++?

The main function must be declared as a non-member function in the global namespace. This means that it cannot be a static or non-static member function of a class, nor can it be placed in a namespace (even the unnamed namespace).

The name main is not reserved in C++ except as a function in the global namespace. You are free to declare other entities named main, including among other things, classes, variables, enumerations, member functions, and non-member functions not in the global namespace.

You can declare a function named main as a member function or in a namespace, but such a function would not be the main function that designates where the program starts.

The main function cannot be declared as static or inline. It also cannot be overloaded; there can be only one function named main in the global namespace.

The main function cannot be used in your program: you are not allowed to call the main function from anywhere in your code, nor are you allowed to take its address.

The return type of main must be int. No other return type is allowed (this rule is in bold because it is very common to see incorrect programs that declare main with a return type of void; this is probably the most frequently violated rule concerning the main function).

There are two declarations of main that must be allowed:

int main()               // (1)
int main(int, char*[]) // (2)

In (1), there are no parameters.

In (2), there are two parameters and they are conventionally named argc and argv, respectively. argv is a pointer to an array of C strings representing the arguments to the program. argc is the number of arguments in the argv array.

Usually, argv[0] contains the name of the program, but this is not always the case. argv[argc] is guaranteed to be a null pointer.

Note that since an array type argument (like char*[]) is really just a pointer type argument in disguise, the following two are both valid ways to write (2) and they both mean exactly the same thing:

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

Some implementations may allow other types and numbers of parameters; you'd have to check the documentation of your implementation to see what it supports.

main() is expected to return zero to indicate success and non-zero to indicate failure. You are not required to explicitly write a return statement in main(): if you let main() return without an explicit return statement, it's the same as if you had written return 0;. The following two main() functions have the same behavior:

int main() { }
int main() { return 0; }

There are two macros, EXIT_SUCCESS and EXIT_FAILURE, defined in <cstdlib> that can also be returned from main() to indicate success and failure, respectively.

The value returned by main() is passed to the exit() function, which terminates the program.

Note that all of this applies only when compiling for a hosted environment (informally, an environment where you have a full standard library and there's an OS running your program). It is also possible to compile a C++ program for a freestanding environment (for example, some types of embedded systems), in which case startup and termination are wholly implementation-defined and a main() function may not even be required. If you're writing C++ for a modern desktop OS, though, you're compiling for a hosted environment.

Function declaration before and after main()

There are two valid signatures for the main() function:

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

Notice that both valid signatures have a return type of int. Any other return type, such as void is not valid and causes the compiler to output a warning message.

When the code calls a function, the compiler needs to know the signature of that called function. There are two ways to tell the compiler what the signature of the called function is:

  1. have the whole function listed before where it is called
  2. have a prototype (aka forward reference) of the function signature before where the function is called. In a prototype the compiler only needs the returned type and the types of the parameters. However, it is a good programming practice to have the names of the parameters listed in the prototype as a courtesy to the humans reading the code.

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.

Definition of main() in C [duplicate]

In C, there's a difference between the declarations int main(); and int main(void); (the former declares a function with an unspecified number of arguments, and the latter is actually called a proto­type). However, in the function definition, both main() and main(void) define a function that takes no arguments.

The other signature, main(int, char**), is an alternative form. Conforming implementations must accept either form, but may also accept other implementation-defined signatures for main(). Any given program may of course only contain one single function called main.

What are the valid signatures for C's main() function?

The C11 standard explicitly mentions these two:

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

although it does mention the phrase "or equivalent" with the following footnote:

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.

In addition, it also provides for more (implementation-defined) possibilities.

The relevant text (section 5.1.2.2.1, but this particular aspect is unchanged from C99) states:

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.

If they are declared, the parameters to the main function shall obey the following constraints:

  • The value of argc shall be nonnegative.

  • argv[argc] shall be a null pointer.

  • If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.

  • If the value of argc is greater than zero, the string pointed to by argv[0] represents the program name; argv[0][0] shall be the null character if the program name is not available from the host environment. If the value of argc is greater than one, the strings pointed to by argv[1] through argv[argc-1] represent the program parameters.

  • The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.

Note that this is for a hosted environment, the ones you normally see in C programs. A free-standing environment (such as an embedded system) is far less constrained, as stated in 5.1.2.1 of that same standard:

In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.

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.

correctly declaring the main() function in ANSI C [duplicate]

Well, if you want ANSI C, then by definition the standard is right.

In C89/C90 the int return type is implied, so the K&R definition would be acceptable.

In C99 this is no longer the case.

The C90 standard has the following wording (5.1.2.2.1 Program startup), which is very similar to the C99 wording (probably most significantly it uses the less strong 'can' instead of 'shall'):

The function called at program startup is named main. The implementation declares no prototype for this function. It can be defined 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[]) { /* ... */ }

If they are defined, the parameters to the main function shall obey the following constraints:

[etc. ...]

There's nothing in that section directly about the fact that leaving off the return type will result in it defaulting to int.

Frankly, I have a hard time finding exactly where that behavior is specified by the standard. The closest I can come is in 6.7.1 (Functions definitions) where the grammar for function definitions indicates that the 'declaration-specifiers' are optional, and the examples say:

Examples:

  1. In the following:

      extern int max(int a, int b)
    {
    return a > b ? a : b;
    }

    extern is the storage class specifier and int is the type specifier (each of which may be omitted as those are the defaults)...

main() function in C

  1. A declaration of a function is needed only before a function is used. The definition is itself a declaration, so no prior prototype is required. (Some compilers and other tools may warn if a function is defined without a prior prototype. This is intended as a helpful guideline, not a rule of the C language.)
  2. Because the C standard says so. Operating systems pass the return value to the calling program (usually the shell). Some compilers will accept void main, but this is a non-standard extension (it usually means "always return zero to the OS").
  3. By convention, a non-zero return value signals that an error occurred. Shell scripts and other programs can use this to find out if your program terminated successfully.

C - Should a function return something especially in main() declaration? [duplicate]

Because many programmers used the second style, causing unspecified exit status to be reported to the system, the C Standard committee decided to make main return 0 implicitly if control leaves its body without a return statement. This behavior is mandated by the C Standard C99 and later versions. As a consequence, return 0; can be omitted by it is better IMHO to still make it explicit.

Note however that it is also considered good style to indent the statements in the body of functions:

int main() {
stuff;
return 0;
}

Note also that the C Standard documents 2 possible prototypes for main:

int main(void);

and

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

or equivalent variants:

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

etc.

Omitting the argument list as you wrote in both examples is supported and would be equivalent to int main(void) in C++, but is not exactly equivalent in C: It means the argument list is unspecified, so the compiler cannot check the arguments passed to main if it encounters a call to main in the program, not can it perform the appropriate conversions.

In this case, it does not matter since the main functions in the examples do not use their arguments and indeed seems more consistent than int main(void) since arguments are indeed passed to it by the startup code.



Related Topics



Leave a reply



Submit