Prototype of "main"

N

Neelesh

Hi all,
it is strange that the following code compiles and runs (tested with
g++ 3.4.2)

#include <iostream>
using namespace std;

int main(int a, int b, int c, int d, int e)
{
cout << "hello " << endl;
}

Is C++ lenient about the prototype of main? Does it say anything if the
prototype is not one of those standard argc-argv-env kinds?
Is the program expected to run in such cases or this is simply by luck
that it runs properly?


Thanks,
Neelesh
 
G

Greg Comeau

Hi all,
it is strange that the following code compiles and runs (tested with
g++ 3.4.2)

#include <iostream>
using namespace std;

int main(int a, int b, int c, int d, int e)
{
cout << "hello " << endl;
}

Is C++ lenient about the prototype of main? Does it say anything if the
prototype is not one of those standard argc-argv-env kinds?
Is the program expected to run in such cases or this is simply by luck
that it runs properly?

As I recall that particular case is implementation-defined. Check out
http://www.comeaucomputing.com/techtalk/#voidmain
 
P

peter koch

Neelesh skrev:
Hi all,
it is strange that the following code compiles and runs (tested with
g++ 3.4.2)

#include <iostream>
using namespace std;

int main(int a, int b, int c, int d, int e)
{
cout << "hello " << endl;
}

Is C++ lenient about the prototype of main? Does it say anything if the
prototype is not one of those standard argc-argv-env kinds?
Is the program expected to run in such cases or this is simply by luck
that it runs properly?

For main only no return value corresponds to return 0. So this is a
very special situation. Your variety with five ints is non-conforming,
however.

/Peter
 
R

Rolf Magnus

peter said:
Neelesh skrev:


For main only no return value corresponds to return 0. So this is a
very special situation. Your variety with five ints is non-conforming,
however.

It's not. An implmentation is required to accept a definition of main() with
either no parameters or the usual argc/argv ones, but it is free to accept
any other parameter list. Only the return type is always required to be
int.
 
P

peter koch

Rolf Magnus skrev:
It's not. An implmentation is required to accept a definition of main() with
either no parameters or the usual argc/argv ones, but it is free to accept
any other parameter list. Only the return type is always required to be
int.
Is that so? I am aware that there is the concept of a freestanding
implementation which has special liberties wrt the the parameters for
main. If that is what you mean, I believe that we agree and that my
wording was a bit to strong. If not, I am surprised if this weirdly
looking main is conforming.

/Peter
 
A

Alf P. Steinbach

* peter koch -> Rolf Magnus:
I am aware that there is the concept of a freestanding
implementation which has special liberties wrt the the parameters for
main. If that is what you mean, I believe that we agree and that my
wording was a bit to strong. If not, I am surprised if this weirdly
looking main is conforming.

Freestanding implementation has nothing to do with it.

The standard requires int result type, and the standard requires support
for two specific signatures (unless its a freestanding implementation).

The implementation is free to support additional signatures, if they all
have int result type.
 
P

peter koch

Alf P. Steinbach skrev:
* peter koch -> Rolf Magnus:


Freestanding implementation has nothing to do with it.

The standard requires int result type, and the standard requires support
for two specific signatures (unless its a freestanding implementation).

The implementation is free to support additional signatures, if they all
have int result type.

Hi Alf

Thanks - always nice to learn something new.

/Peter
 
D

Default User

peter said:
Alf P. Steinbach skrev:


Hi Alf

Thanks - always nice to learn something new.


Many for unix systems, it was (is) common to have main() declared as:

int main(int argc, char **argv, char **envp)


The third argument would give you the process's environment variable
list. This is so convenient that people often ask about it when their
implementation doesn't support it. See also:

http://www.eskimo.com/~scs/C-faq/q11.13.html




Brian
 
K

Kaz Kylheku

Greg said:
As I recall that particular case is implementation-defined. Check out
http://www.comeaucomputing.com/techtalk/#voidmain

The program's behavior is undefined, because implementations are not
required to support that form of main.

A program that uses a feature for which the support is
implementation-defined in fact invokes undefined behavior.

I would say that the definition

int main(int a, int b, int c, int d, int e) { /* ... */ }

is /worse/ than one returning void! The reason is that no diagnostic is
required! A diagnostic is required if the return type is other than
int. (In that case, the C++ implementation can still translate and
execute the program anyway, but its behavior is undefined).

Anything other than int main() or int main(int, char **) runs by dumb
luck, or by means of being supported as an extension, which has nothing
to do with the standard other than being allowed with or without a
diagnostic, depending on whether the return type is int.

A long ago I wrote this:

http://users.footprints.net/~kaz/cppvoidmain.html

That document is based on the draft C++ standard, so it may be
inaccurate.
 
G

Greg

Kaz said:
The program's behavior is undefined, because implementations are not
required to support that form of main.

Implementation-defined behavior is not undefined behavior. So without
knowing anything about the implementation, it is not possible to
conclude whether this program's behavior is undefined or not. It is
possible to determine whether the program's behavior is defined for a
given compiler, because all implementation-defined behavior must be
documented. So in this case, it is necessary only to consult the
"implementation-defined behavior" section of the compiler's
documentation to find out what it says about arguments to main.
A program that uses a feature for which the support is
implementation-defined in fact invokes undefined behavior.

No, it invokes the behavior that the implementation, and not the
Standard, has defined for it.
I would say that the definition

int main(int a, int b, int c, int d, int e) { /* ... */ }

is /worse/ than one returning void! The reason is that no diagnostic is
required! A diagnostic is required if the return type is other than
int. (In that case, the C++ implementation can still translate and
execute the program anyway, but its behavior is undefined).

Anything other than int main() or int main(int, char **) runs by dumb
luck, or by means of being supported as an extension, which has nothing
to do with the standard other than being allowed with or without a
diagnostic, depending on whether the return type is int.

The C++ standard specifically leaves some questions - such as the size
of a byte or additional declarations of main - up to each
implementation to decide on its own. It does so because it recognizes
that a "one-size-fits-all" approach is not always practicable for all
types of processors and OS'es. Instead it is better to have each
implementation be responsible for deciding these types of issues and
for documenting the decision. So any C++ program whose behavior is
defined by either the Standard or by the implementation is a valid and
perfectly acceptable C++ program.

Greg
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top