What declarations of main exist in the c standard?

B

bjrnove

Hi.

Me and a friend have a discussion about main. In my opinion the legal
ways of writing main is:

int main(void);
int main(int,char**);

My friend claims that you also have a standard version with enviroment
variables like this:
int main(int,char**,char**);

Is that right or are my two versions the only standard c way to do it?
 
E

Eric Sosman

bjrnove said:
Hi.

Me and a friend have a discussion about main. In my opinion the legal
ways of writing main is:

int main(void);
int main(int,char**);

My friend claims that you also have a standard version with enviroment
variables like this:
int main(int,char**,char**);

Is that right or are my two versions the only standard c way to do it?

The Standard guarantees that any hosted C implementation
must accept your two forms. The Standard allows an implementation
to accept other forms, too, but does not describe any of those
implementation-specific alternative forms and does not require that
other implementations accept them.

To put it another way: The two forms you describe are the
only two forms that are guaranteed to work on all implementations.
Alternative non-Standard forms may work on some implementations,
but are not required to work on all -- they are not even required
to work in the same way for all implementations where they "work"
at all.
 
B

bjrnove

The Standard guarantees that any hosted C implementation
must accept your two forms. The Standard allows an implementation
to accept other forms, too, but does not describe any of those
implementation-specific alternative forms and does not require that
other implementations accept them.
To put it another way: The two forms you describe are the
only two forms that are guaranteed to work on all implementations.
Alternative non-Standard forms may work on some implementations,
but are not required to work on all -- they are not even required
to work in the same way for all implementations where they "work"
at all.

Exactly the way I though it was. Thanks..
 
W

Walter Roberson

Exactly the way I though it was. Thanks..

The presence of the third argument with environment variable
information is a common Unix extension -- but it isn't even
part of the Unix specification (which imports the POSIX.1
specification):

http://www.opengroup.org/onlinepubs/009695399/functions/exec.html

The exec family of functions shall replace the current process
image with a new process image. The new image shall be constructed
from a regular, executable file called the new process image file.
There shall be no return from a successful exec, because the
calling process image is overlaid by the new process image.

When a C-language program is executed as a result of this call, it
shall be entered as a C-language function call as follows:

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

where argc is the argument count and argv is an array of character
pointers to the arguments themselves. In addition, the following
variable:

extern char **environ;


is initialized as a pointer to an array of character pointers to
the environment strings. The argv and environ arrays are each
terminated by a null pointer. The null pointer terminating the argv
array is not counted in argc.
 
M

Mark

Eric Sosman said:
The Standard guarantees that any hosted C implementation
must accept your two forms. The Standard allows an implementation
to accept other forms, too, but does not describe any of those
implementation-specific alternative forms
<snip>

Actually, it does 'describe' one of those 'other forms'.

J.5.1 Environment arguments
[#1] 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).
 
E

Eric Sosman

Mark said:
Eric Sosman said:
The Standard guarantees that any hosted C implementation
must accept your two forms. The Standard allows an implementation
to accept other forms, too, but does not describe any of those
implementation-specific alternative forms

<snip>

Actually, it does 'describe' one of those 'other forms'.

J.5.1 Environment arguments
[#1] 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).

Foreword, paragraph 6: "Annexes D and F form a normative
part of this standard; annexes A,B,C,E,G,H,I,J, [...] are for
information only."

So, yes: an alternative main() is "described," but not in
normative text -- the "description" has no force, and the O.P.
is correct not to rely on a third argument's presence.
 
J

Joe Wright

Eric said:
The Standard guarantees that any hosted C implementation
must accept your two forms. The Standard allows an implementation
to accept other forms, too, but does not describe any of those
implementation-specific alternative forms

<snip>

Actually, it does 'describe' one of those 'other forms'.

J.5.1 Environment arguments
[#1] 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).


Foreword, paragraph 6: "Annexes D and F form a normative
part of this standard; annexes A,B,C,E,G,H,I,J, [...] are for
information only."

So, yes: an alternative main() is "described," but not in
normative text -- the "description" has no force, and the O.P.
is correct not to rely on a third argument's presence.

References to the C Standard notwithstanding, I present an observation:
I have written two little non-compliant/non-conforming C programs.

C:\work\c\clc>cat env.c
#include <stdio.h>
extern char **environ;
int main(void) {
int i = 0;
char *env;
while ((env = environ[i++]))
puts(env);
return 0;
}

C:\work\c\clc>cat env2.c
#include <stdio.h>
int main(int c, char **argv, char **environ) {
int i = 0;
char *env;
while ((env = environ[i++]))
puts(env);
return 0;
}

They both "work" on every implementation I have access to. Would y'all
try these at your house? I betcha every NIX takes it, and OS-X from
Apple. Every MS implementation will take it. Where will these not "work"?
 
O

Old Wolf

Joe said:
They both "work" on every implementation I have access to. Would y'all
try these at your house? I betcha every NIX takes it, and OS-X from
Apple. Every MS implementation will take it. Where will these not "work"?

I have written two little non-compliant/non-conforming C programs.

#include <stdio.h>
extern char **environ;
int main(void) {
int i = 0;
char *env;
while ((env = environ[i++]))
puts(env);
return 0;
}

"main.c", line 7 pos 8; (W) [ANSI] missing prototype for "puts"
ERROR: (A320) UNRESOLVED EXTERNALS:
SYMBOL MODULE
_environ main
_puts main

(Note - freestanding implementation)
 
R

Richard Bos

Joe Wright said:
Eric said:
Foreword, paragraph 6: "Annexes D and F form a normative
part of this standard; annexes A,B,C,E,G,H,I,J, [...] are for
information only."

So, yes: an alternative main() is "described," but not in
normative text -- the "description" has no force, and the O.P.
is correct not to rely on a third argument's presence.

References to the C Standard notwithstanding, I present an observation:
I have written two little non-compliant/non-conforming C programs.

C:\work\c\clc>cat env.c
#include <stdio.h>
extern char **environ;
C:\work\c\clc>cat env2.c
#include <stdio.h>
int main(int c, char **argv, char **environ) {
They both "work" on every implementation I have access to. Would y'all
try these at your house? I betcha every NIX takes it, and OS-X from
Apple.

They would accept at least the first; POSIX requires it. But not, I
hope, in ISO-compatible mode.
Every MS implementation will take it.

I hope that you mean "every implementation written by MS", not "every
implementation for an MS OS", because the latter is false:

# Building test.exe.
# POLINK: error: Unresolved external symbol '_environ'.
#
# POLINK: fatal error: 1 unresolved external(s).
#
# *** Error code: 1 ***
# Done.

That's Pelles C, BTW. It accepts version 2, but with a warning; and when
run, it causes a GPF.

Dev-C++, interestingly enough, accepts the latter but not the former.
Which, of course, would be correct for an ISO C implementation, since
the first program is simply incorrect - environ is not an identifier the
implementation is allowed to define in ISO C mode - while the second
causes undefined behaviour, allowing the implementation to accept it.

Richard
 
C

Chris Croughton

References to the C Standard notwithstanding, I present an observation:
I have written two little non-compliant/non-conforming C programs.

C:\work\c\clc>cat env.c
#include <stdio.h>
extern char **environ;
int main(void) {
int i = 0;
char *env;
while ((env = environ[i++]))
puts(env);
return 0;
}

Borland C++ 5.6 for Win32 Copyright (c) 1993, 2002 Borland
c:\cygwin\tmp\1.c:
Warning W8060 c:\cygwin\tmp\1.c 6: Possibly incorrect assignment in
function main
Turbo Incremental Link 5.60 Copyright (c) 1997-2002 Borland
Error: Unresolved external '_environ' referenced from D:\HOME\CC\1.OBJ
They both "work" on every implementation I have access to. Would y'all
try these at your house? I betcha every NIX takes it, and OS-X from
Apple. Every MS implementation will take it. Where will these not "work"?

Borland C for a start (although it announces itself as C++ it, like GCC
and the MS compilers, is also a C compiler when invoked to compile a .c
file).

Chris C
 
M

Michael Wojcik

References to the C Standard notwithstanding, I present an observation:
I have written two little non-compliant/non-conforming C programs.

[example one uses "extern char **environ"]
[example two uses a third parameter to main]

They both "work" on every implementation I have access to. Would y'all
try these at your house? I betcha every NIX takes it, and OS-X from
Apple. Every MS implementation will take it. Where will these not "work"?

ILE C for AS/400: the first program compiles but abends immediately
when run with a machine check (MCH3601), no doubt due to dereferencing
the "environ" pointer. The second program compiles and runs but
displays nothing, which is within the bounds of undefined behavior.

--
Michael Wojcik (e-mail address removed)

This is a "rubbering action game," a 2D platformer where you control a
girl equipped with an elastic rope with a fishing hook at the end.
-- review of _Umihara Kawase Shun_ for the Sony Playstation
 
J

Joe Wright

Joe said:
Eric said:
The Standard guarantees that any hosted C implementation
must accept your two forms. The Standard allows an implementation
to accept other forms, too, but does not describe any of those
implementation-specific alternative forms


<snip>

Actually, it does 'describe' one of those 'other forms'.

J.5.1 Environment arguments
[#1] 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).



Foreword, paragraph 6: "Annexes D and F form a normative
part of this standard; annexes A,B,C,E,G,H,I,J, [...] are for
information only."

So, yes: an alternative main() is "described," but not in
normative text -- the "description" has no force, and the O.P.
is correct not to rely on a third argument's presence.

References to the C Standard notwithstanding, I present an observation:
I have written two little non-compliant/non-conforming C programs.

C:\work\c\clc>cat env.c
#include <stdio.h>
extern char **environ;
int main(void) {
int i = 0;
char *env;
while ((env = environ[i++]))
puts(env);
return 0;
}

C:\work\c\clc>cat env2.c
#include <stdio.h>
int main(int c, char **argv, char **environ) {
int i = 0;
char *env;
while ((env = environ[i++]))
puts(env);
return 0;
}

They both "work" on every implementation I have access to. Would y'all
try these at your house? I betcha every NIX takes it, and OS-X from
Apple. Every MS implementation will take it. Where will these not "work"?

I want to thank y'all for the thoughtful responses. My own annecdotal
experience notwithstanding, they're not widely portable. Thank you.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top