main can't be void [duplicate] - c++

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
does c++ standard prohibit the void main() prototype?
Why is C++ not letting me do void main()? It's not much of a problem, but I'm still curious.

Because return type of main()(as mandated by the Standard) must be int
C++03 [Section 3.6.1 Main function]
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.

Answer from Stroustrup himself:
Can I write "void main()"?
The definition
void main() { /* ... */ }
is not and never has been C++, nor has it even been C. See the ISO C++ standard 3.6.1[2] or the ISO C standard 5.1.2.2.1. A conforming implementation accepts
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
A conforming implementation may provide more versions of main(), but they must all have return type int. The int returned by main() is a way for a program to return a value to "the system" that invokes it. On systems that doesn't provide such a facility the return value is ignored, but that doesn't make "void main()" legal C++ or legal C. Even if your compiler accepts "void main()" avoid it, or risk being considered ignorant by C and C++ programmers.
In C++, main() need not contain an explicit return statement. In that case, the value returned is 0, meaning successful execution. For example:
#include<iostream>
int main()
{
std::cout << "This program returns the integer value 0\n";
}
Note also that neither ISO C++ nor C99 allows you to leave the type out of a declaration. That is, in contrast to C89 and ARM C++ ,"int" is not assumed where a type is missing in a declaration. Consequently:
#include<iostream>
main() { /* ... */ }
is an error because the return type of main() is missing.
Source: http://www2.research.att.com/~bs/bs_faq2.html#void-main

Because the standard says that it returns int.

Some operating systems expect an integral return value from processes. Declare main to return an int. If you don't care about the value, simply return 0.
From the comp.lang.c FAQ:
"What's the correct declaration of main?" (There are two: no args, and argc/argv.)
Can I declare main as void, to shut off these annoying ``main returns no value'' messages? (Short answer: No)

Related

why does my code sayserror: ld returned 1 exit status? [duplicate]

Questions
What is the proper signature of the main function in C++?
What is the correct return type, and what does it mean to return a value from main?
What are the allowed parameter types, and what are their meanings?
Is this system-specific?
Have those rules changed over time?
What happens if I violate them?
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.
From Standard docs., 3.6.1.2 Main Function,
It shall have a return
type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following
definitions of main:
int main() { / ... / } and
int main(int argc, char* argv[]) { / ... / }
In the latter form argc shall be the number of arguments passed to the program from the environment in which the
program is run.If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to
the initial characters of null-terminated multibyte strings.....
Hope that helps..
The exact wording of the latest published standard (C++14) is:
An implementation shall allow both
a function of () returning int and
a function of (int, pointer to pointer to char) returning int
as the type of main.
This makes it clear that alternative spellings are permitted so long as the type of main is the type int() or int(int, char**). So the following are also permitted:
int main(void)
auto main() -> int
int main ( )
signed int main()
typedef char **a; typedef int b, e; e main(b d, a c)
The two valid mains are int main() and int main(int, char*[]). Any thing else may or may not compile. If main doesn't explicitly return a value, 0 is implicitly returned.
Details on return values and their meaning
Per 3.6.1 ([basic.start.main]):
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;
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.

C/C++ - how is (void) used not as a parameter? [duplicate]

This question already has answers here:
in c: func(void) vs. func() [duplicate]
(2 answers)
Closed 9 years ago.
I have seen some code in C/C++ that goes like this:
void Main(void)
And
int Main(void)
What is the reasoning for this: why is it not a parameter but used in parentheses after the void/int e.t.c name?
void in a parameter list is effectively a keyword, not specifying the type of anything. The reason for its existence is purely historical.
Early C did not have function prototypes or any syntax for parameter lists. A function definition would look like this:
foo()
int x; // These are the parameters.
float y;
{
return x + (int) y;
}
There was "no need" for prototypes because the compiler would assume every call passed exactly the correct type and number of arguments. This was error-prone. Furthermore the return type was assumed to be int, which is an even more brittle assumption. The first prototypes specified only the return type.
float foo(); // Still no parameters.
When the familiar float foo( int x, float y ) syntax was introduced, backward compatibility with the preceding style was retained. The void keyword was used to differentiate between an indeterminate (missing) parameter list and an empty parameter list.
In C, float foo() and float foo( void ) mean different things to this day.
In C++, indeterminate parameter lists are unsupported, and float foo( void ) is a discouraged, but not deprecated, synonym for float foo().
Furthermore C++ allows templates to determine the type of an argument, but generating a (void) parameter list by a template is an error.
In C (void) means that there is no arguments required in function call, while () means unspecified number of arguments. In C++. () means the same as (void)
Here is what C standard says
5.1.2.1 Freestanding environment
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.
/ .. / The effect of program termination in a freestanding environment
is implementation-defined.
5.1.2.2 Hosted environment
A hosted environment need not be provided, but shall conform to the
following specifications if present.
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[]) { /* ... */ }
In C this
void func() {
}
means a function that takes an indeterminate number of arguments. If you want to write a function that takes zero arguments you do this
void func(void) {
}
The reasons for this are in the history of the C language, they don't make much sense otherwise. For this reason C++ changed the rules. In C++ the first example above means a function that takes zero arguments, and this
void func(int x, ...) {
}
means a function that takes a variable number of arguments (one or more in this case). C will also accept this.
So in C and C++, example 2 means zero arguments and example 3 means a variable number of arguments, but C and C++ disagree on what example 1 means, for C it's an indeterminate number of arguments, for C++ it's zero arguments.
If you see (void) in a C++ program it's either code that has been ported from C and no-one has bothered to change it, or it's code which is expected to be compiled as both C and C++ (in a header file for instance).
Draft n1570;
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.....)
It is clear from the C standard that void is used for a function having no parameter.
In c++, sometimes parameter "names" may be excluded if they are not called from within the function. If you know that you will use it, you may add the parameter name by yourself. It would hardly make sense for the void parameter of main, though.
In old compilers it was mandate to specify void in parenthesis in case main is not going to accept any parameters. but these days you may need to use like only:
void main()

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

I know that in C compilers the main() function is called by the _start() function which has code something like this:
exit(main()); // return value of main is returned
How does _start() work when main() does not return int, for example if its return type is void, float, or something else?
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 C standard never mentions this _start function; I don't believe C++ does either.
In C prior to the 1999 ISO standard, if execution reaches the end of main() without executing a return statement, or executes a return statement that doesn't specify a value, then "the termination status returned to the host environment is undefined". In practice, I've seen implementations where such a program returns a status of 1 (failure), or some arbitrary value in memory such as the result of the last function that was called.
The 1999 ISO C standard changed this: "reaching the } that terminates the main function returns a value of 0". This matches the rule that C++ has had at least since the first ISO C++ standard in 1998.
(As a matter of style, I prefer to have an explicit return 0; at the end of main, even if it's not strictly required. This is consistent with int functions other than main, and it makes for better portability to pre-C99 C compilers.)
All this assumes that main is defined with a return type of int. That's the only type that's specifically supported by the C standard (either int main(void) or int main(int argc, char *argv[]) or equivalent), but (hosted) implementations may support other implementation-defined definitions. The C90 standard doesn't explicitly cover this case, but C99 says, "If the return type is not compatible with int, the termination status returned to the host environment is unspecified."
The C++ standard is a bit different. For hosted implementations, main must be defined to return int. The parameters are implementation-defined, but both the standard forms of C must be supported.
For a hosted implementation in either C or C++, there is no good reason I know of to define main with a return type other than int. Just use one of the two standard definitions, and the question won't arise.
For "freestanding implementations", "the name and type of the function called at program
startup are implementation-defined". So the entry point might legitimately return void or something else, and it might not even be called main. Note that a "freestanding implementation" is one "in which C program execution may take place without any
benefit of an operating system", typically an embedded system.
The function will return an implementation-defined value. For example, in C++, main implicitly returns 0. In this case of a void main then this would simply be returned by _start. However, there are virtually no implementations that would allow any arbitrary return type- it's baked into the operating system that a process exits with an integral value.
In C++ it would be a compile error to return anything other than int from main():
error: ‘::main’ must return ‘int’
In C it is a warning, you will get a float reinterpreted as an int: for example, 2.1F would be reinterpreted as 224.
Standard implementations of C expect main to return int just because it is defined that way in the C standard. Returning something other than int (or a type compatible with int) usually results in undefined behaviour—meaning there is no way to tell what will happen.
However, there are non-standard implementations of C, for example, the Plan 9 operating system uses void main(), here is a list their utilities&apos; source code. Plan 9 C code is quite a bit different to K&R, ANSI, C99 or C11. Here's a link explaining how Plan 9 uses the C language.
If the return type of main is not an int then the return value is implementation defined.
In short an Implementation is allowed to have different return type than int for main but none of the known implementations support anything other than int.
Ideally, You will need to refer to the documentation of your platform and the compiler to see what exact behavior it defines because it is allowed to have the flexibility do so by the standard.
Reference:
C++03 Standard:
3.6.1 Main function [basic.start.main]
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
.....
The C-standard does not allow you to return any other value than int or void -- the c-compiler specifically test for the signature of main to make sure it is compatible.
Assume we're using Visual Studio 2012.
For C++ programs, Visual Studio allows void to be specified as the return type, even though this is forbidden by the C++ standard. Under the standard, main() must return an int in hosted implementations.
For C programs, any return type is allowed for main(), but returning something other than an int results in unspecified behavior. For example, under Visual Studio 2012, returning 0.0 from double main() results in a return value of 0xcccccccc when the program is run in the debugger (see In Visual Studio C++, what are the memory allocation representations?).

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

Questions
What is the proper signature of the main function in C++?
What is the correct return type, and what does it mean to return a value from main?
What are the allowed parameter types, and what are their meanings?
Is this system-specific?
Have those rules changed over time?
What happens if I violate them?
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.
From Standard docs., 3.6.1.2 Main Function,
It shall have a return
type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following
definitions of main:
int main() { / ... / } and
int main(int argc, char* argv[]) { / ... / }
In the latter form argc shall be the number of arguments passed to the program from the environment in which the
program is run.If argc is nonzero these arguments shall be supplied in argv[0] through argv[argc-1] as pointers to
the initial characters of null-terminated multibyte strings.....
Hope that helps..
The exact wording of the latest published standard (C++14) is:
An implementation shall allow both
a function of () returning int and
a function of (int, pointer to pointer to char) returning int
as the type of main.
This makes it clear that alternative spellings are permitted so long as the type of main is the type int() or int(int, char**). So the following are also permitted:
int main(void)
auto main() -> int
int main ( )
signed int main()
typedef char **a; typedef int b, e; e main(b d, a c)
The two valid mains are int main() and int main(int, char*[]). Any thing else may or may not compile. If main doesn't explicitly return a value, 0 is implicitly returned.
Details on return values and their meaning
Per 3.6.1 ([basic.start.main]):
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;
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.

Can the arguments of main's signature in C++ have the unsigned and const qualifiers? [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 5 years ago.
The standard explicitly states that main has two valid (i.e., guaranteed to work) signatures; namely:
int main();
int main(int, char*[]);
My question is simple, would something like the following be legal?
int main(const unsigned int, const char* const* argv);
My tests say 'yes', but I'm unsure of the answer because am I not overloading main by changing int to unsigned int as well as the non top-level const-ness of argv? If I am, then that's clearly prohibited.
So, are these modifications guaranteed to work on a standards conforming compiler?
The C++98 standard says in section 3.6.1 paragraph 2
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both the following definitions of main: int main() and int main(int argc, char* argv[])
So it's not mandated by the standard that the env accepting main is acceptable but it is permissible.
Because this is referred to often, here is the previous paragraph exempting freestanding environments from anything but documenting their behavior:
A program shall contain a global function called main, which is the designated start of the program. It is
implementation defined
whether a program in a freestanding environment is required to define a main
function. [Note: in a freestanding environment, startup
and termination is implementation defined;
startup
contains the execution of constructors for objects of namespace scope with static storage duration; termination
contains the execution of destructors for objects with static storage duration. ]
You must use one of the standard-conformant signatures to be standard-conformant.
I fully understand why you want to do it your way. The best way is to write your own function myMain() or whatever with the signature you want and call it from main(), including the required casts.
The argv pointers shouldn't be const char* const because the program is allowed to change the buffers.
As far as I can see from reading the standard, you're being non-standards-compliant. But I can't imagine a compiler that wouldn't let you do this. As in, it'd take more work from the compiler to specifically ban an edge case that is mostly harmless and very obscure.
This may not work if the compiler uses name mangling for main. It's a C++ function after all. Hence, the linker will be looking for two particular "manglings". Your definition would have another mangled name.
Note that main is special (doesn't overload, not callable) and might not require name mangling at all.
You might be illegal by the standard, but most runtimes don't really care. They'll just push an integer for argc and a pointer for argv, call your main, and hope you parse them right. So, in your purview, "guaranteed to work" is debatable as the loader really doesn't care what you've declared the arguments as.
If it builds, main will get called. How you parse the arguments is up to you. I should clarify that this is highly platform-specific, as is nearly this entire question.
That said, why?
ISO/IEC 9899:TC3
Section 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;9) or in some other implementation-defined manner.