return from main

J

jameskuyper

Charlie said:
"James Kuyper" <[email protected]> a écrit dans le message de news: ....

I should have said "roughly equivalent". I was aware of the exception
you describe:
There is a subtle difference: calling exit() from main invokes the functions
registered with atexit with main's local variables still valid. Returning
from main will invoke exit with the return value, but main's local variables
will have been destroyed and any function registered with atexit referencing
them invokes undefined behaviour, that applies to the argc argv arguments
and potentially also to the strings pointed to by the argv array.

In practice, I doubt that this case comes up very often. I didn't want
to complicate my response further by mentioning that exception.
 
S

Spiros Bousbouras

Saying that the return type of main() is implementation defined may be
a little bit misleading. All hosted implementations must support a
return type of int.

We must be reading the beginning of 5.1.2.2.1 differently.
I read it as:

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
or in some other implementation-defined manner.

The 1st sentence, which I didn't quote, says the starting
point has to be main but, apart from the name, main can
be anything the implementation likes (as long as it's
documented).
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

We must be reading the beginning of 5.1.2.2.1 differently.

I don't believe you are. Let's say a silly implementation supports
char main(int argc, wchar_t *argv[])
as an extension. It doesn't have to also allow
int main(int argc, wchar_t *argv[])
but since it still must support
int main(int argc, char *argv[])
it does have to support a return type of int. This is consistent with
both your message and Keith's, unless I am the one misreading here.
 
K

Keith Thompson

Spiros said:
Saying that the return type of main() is implementation defined may be
a little bit misleading. All hosted implementations must support a
return type of int.

We must be reading the beginning of 5.1.2.2.1 differently.
I read it as:

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
or in some other implementation-defined manner.

The 1st sentence, which I didn't quote, says the starting
point has to be main but, apart from the name, main can
be anything the implementation likes (as long as it's
documented).

Yes, which why I said it "may be a little bit misleading" rather than "it's wrong".

An implementation *must* support the two standard forms:
int main(void)
int main(int argc, char *argv[])
and equivalents. It *may* document and support additional forms, but using such
alternate forms is usually unwise.

Merely saying that it's implementation defined fails to emphasize the standard
forms.
 
P

Peter Nilsson

Keith Willis said:
Since posting the link to Stroustrup's PDF, I've been
looking for the source of the original comments by
Ritchie and McIlroy, but no luck.

Chances are it was a corridor discussion.
 
B

Barry Schwarz

The reason why I had a trouble understanding the lines is due to the
fact that, I was interpreting these lines as follows:

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

I was interpreting the above as a single line.
http://en.wikipedia.org/wiki/Semicolon

Perhaps, if they would have used "Reaching" instead of "reaching",

And replaced the semicolon with a period (full stop)
it would have been easier for the readers to undertsnat it as follows:

Expecting others to impoverish their writing simply due to ignorance of
punctuation seems a little unfair...

[Note - "ignorance" here is used in a purely descriptive sense. I tend
to favour ignorance over stupidity, as ignorance is curable]

Considering that it is supposed to be an international standard, it
wouldn't hurt for the writers to consider their readers for whom
English is not the native language. However, since it was written by
committee, clarity was probably not a primary consideration.

In any case, the sentence expresses two completely unrelated, actually
mutually exclusive, concepts. It would hardly impoverish the writing
if they gave each concept its own sentence.


Remove del for email
 
C

Christopher Benson-Manica

[comp.lang.c] Keith Willis said:
Since posting the link to Stroustrup's PDF, I've been looking for the
source of the original comments by Ritchie and McIlroy, but no luck.
All the links point back to Stroustrup saying that Ritchie and McIlroy
called it an abomination, but that document carries no cites or
references. If anyone knows, I'd be mildly interested to read the
original comments and rationale.

This isn't really an answer, but I (in my five-months-out-of-college
incarnation) asked a question somewhat along the same lines in 2003;
you might find the esteeemed Mr. Plauger's response to be interesting:
http://snurl.com/1to5s (links to the Google Groups thread).
 
S

Spiros Bousbouras

We must be reading the beginning of 5.1.2.2.1 differently.
I read it as:
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
or in some other implementation-defined manner.
The 1st sentence, which I didn't quote, says the starting
point has to be main but, apart from the name, main can
be anything the implementation likes (as long as it's
documented).

Yes, which why I said it "may be a little bit misleading" rather than "it's wrong".

An implementation *must* support the two standard forms:
int main(void)
int main(int argc, char *argv[])
and equivalents. It *may* document and support additional forms, but using such
alternate forms is usually unwise.

Merely saying that it's implementation defined fails to emphasize the standard
forms.

How does it follow from the part of the standard that I quoted
that it has to support the two standard forms ? It seems to me
that as long as it satisfies the indented part below the or
meaning the part reading "or in some other implementation-defined
manner" then it can ignore the part above the or. If one of the
two clauses of an or is satisfied then that's good enough , isn't
it ? Although reading the 2nd paragraph of 5.1.2.2.1 perhaps
the intention was that it must always satisfy the part above the
or. If that was the intention then it's not at all clearly phrased.
 
P

Philip Potter

Spiros said:
Spiros said:
The return type of main() is implementation defined.
Saying that the return type of main() is implementation defined may be
a little bit misleading. All hosted implementations must support a
return type of int.
We must be reading the beginning of 5.1.2.2.1 differently.
I read it as:
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
or in some other implementation-defined manner.
The 1st sentence, which I didn't quote, says the starting
point has to be main but, apart from the name, main can
be anything the implementation likes (as long as it's
documented).
Yes, which why I said it "may be a little bit misleading" rather than "it's wrong".

An implementation *must* support the two standard forms:
int main(void)
int main(int argc, char *argv[])
and equivalents. It *may* document and support additional forms, but using such
alternate forms is usually unwise.

Merely saying that it's implementation defined fails to emphasize the standard
forms.

How does it follow from the part of the standard that I quoted
that it has to support the two standard forms ? It seems to me
that as long as it satisfies the indented part below the or
meaning the part reading "or in some other implementation-defined
manner" then it can ignore the part above the or. If one of the
two clauses of an or is satisfied then that's good enough , isn't
it ? Although reading the 2nd paragraph of 5.1.2.2.1 perhaps
the intention was that it must always satisfy the part above the
or. If that was the intention then it's not at all clearly phrased.

My reading of this is that 5.1.2.2.1 provides a list of valid
definitions of main - it shall be defined as 'int main(void)', 'int
main(int argc, char *argv[])', or some implementation-defined definition.

It therefore follows that a conforming hosted implementation must accept
'int main(void)' and 'int main(int argc, char *argv[])', because both
are possible according to the standard.

Your interpretation opens up all sorts of silliness. Consider n1256,
6.5.6p2:
"For addition, either both operands shall have arithmetic type, or one
operand shall be a pointer to an object type and the other shall have
integer type. (Incrementing is equivalent to adding 1.)"

Does this mean the implementation can reject pointer arithmetic because
it can ignore that side of the "either-or" expression?
 
?

=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0F

Spiros said:
The return type of main() is implementation defined.
Saying that the return type of main() is implementation defined may
be a little bit misleading. All hosted implementations must support
a return type of int.
We must be reading the beginning of 5.1.2.2.1 differently. I read it
as:
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
or in some other implementation-defined manner.
The 1st sentence, which I didn't quote, says the starting point has
to be main but, apart from the name, main can be anything the
implementation likes (as long as it's documented).

Yes, which why I said it "may be a little bit misleading" rather than
"it's wrong".

An implementation *must* support the two standard forms:
int main(void)
int main(int argc, char *argv[])
and equivalents. It *may* document and support additional forms, but
using such
alternate forms is usually unwise.

Merely saying that it's implementation defined fails to emphasize the
standard forms.

How does it follow from the part of the standard that I quoted that it
has to support the two standard forms ?

Okay, I misunderstood your point in my previous message.

5.1.2.2.1 describes the forms a program may use. A program that defines
main as int main(void) doesn't violate 5.1.2.2.1. A program that defines
main as char main(float x), when the implementation documents this as an
allowed form, also doesn't violate 5.1.2.2.1. This is what "or" means
here. It does not specify any requirements or permissions for
implementations directly; that's handled by section 4, "Conformance".
Section 4 states that a correct program must be translated as specified,
and since a correct program may define int main(void), implementations
must accept it.
 
K

Keith Thompson

Spiros Bousbouras wrote:
[...]
How does it follow from the part of the standard that I quoted
that it has to support the two standard forms ? It seems to me
that as long as it satisfies the indented part below the or
meaning the part reading "or in some other implementation-defined
manner" then it can ignore the part above the or. If one of the
two clauses of an or is satisfied then that's good enough , isn't
it ? Although reading the 2nd paragraph of 5.1.2.2.1 perhaps
the intention was that it must always satisfy the part above the
or. If that was the intention then it's not at all clearly phrased.

5.1.2.2.1 specifies requirements for a program, not for an implementation. Note
paragraph 1: "It shall be defined ...". The implementation doesn't define main;
the program does. The implementation's job is to accept any program that meets
the requirements.
 
C

Charlie Gordon

Christopher Benson-Manica said:
[comp.lang.c] Keith Willis said:
Since posting the link to Stroustrup's PDF, I've been looking for the
source of the original comments by Ritchie and McIlroy, but no luck.
All the links point back to Stroustrup saying that Ritchie and McIlroy
called it an abomination, but that document carries no cites or
references. If anyone knows, I'd be mildly interested to read the
original comments and rationale.

This isn't really an answer, but I (in my five-months-out-of-college
incarnation) asked a question somewhat along the same lines in 2003;
you might find the esteeemed Mr. Plauger's response to be interesting:
http://snurl.com/1to5s (links to the Google Groups thread).

Interesting indeed! I was about to post that I thought the quote was
probably invented...
 
P

Peter Nilsson

Perhaps none now, but in the past it was certainly a
possibility on some of the VAX systems.
Obscure exceptions: recursive calls to main() and
atexit()-registered functions that refer to local
variables declared in main().

Perhaps more critical to that scenario is that
EXIT_FAILURE need not have a non-zero value or be
different to EXIT_SUCCESS.
 
K

Keith Thompson

Peter said:
Perhaps none now, but in the past it was certainly a
possibility on some of the VAX systems.

Under VMS (which isn't quite dead, and runs on both VAX and Alpha
hardware, and possibly others), the OS convention is that returning an
even number from a program indicates success, and returning an odd
number indicates failure. This obviously conflicts with the convention
of using exit(0) to indicate success. However, the C runtime works
around this by translating "exit(0)" or "return 0" so that it returns
the value 1 (indicating success) to the environment. It *doesn't* do a
similar translation for "exit(1)".

As I recall (from using VMS about 10 years ago), EXIT_SUCCESS is defined
as 0, and EXIT_FAILURE is defined as some non-zero even number (perhaps
2). So exit(0) and exit(EXIT_SUCCESS) are exactly equivalent, even
under VMS.

This may have been different in the distant past.
Perhaps more critical to that scenario is that
EXIT_FAILURE need not have a non-zero value or be
different to EXIT_SUCCESS.

True, but if the OS provides a way for a program to indicate success or
failure, it will almost certainly define EXIT_FAILURE as a non-zero
value different from the value of EXIT_SUCCESS. If the OS has no such
mechanism, then the C implementation might as well define both
EXIT_SUCCESS and EXIT_FAILURE as 0 -- but I don't know of any such systems.

Given that both exit(0) and exit(EXIT_SUCCESS) must indicate success (if
that's possible), I can't think of any reason for EXIT_SUCCESS to have a
value other than 0.

In my opinion, requiring exit(0) (or return 0) to denote success was an
over-specification. Traditionally, in Unix, exit(0) indicates success,
and exit(1) indicates a non-specific failure. The C standard broke the
latter, but not the former.

I suppose the rationale was that if there were no guarantees about
exit(0), then any program that wants to terminate normally must have a
"#include <stdlib.h>" so it can use EXIT_SUCCESS.

If C89 hadn't required 0 to denote success, then C99's rule about
falling off the end of main would actually have made sense; it could
have said that reaching the closing "}" is equivalent to returning
EXIT_SUCCESS. But that's not what happened.
 
B

Ben Pfaff

Keith Thompson said:
Under VMS (which isn't quite dead, and runs on both VAX and Alpha
hardware, and possibly others), the OS convention is that returning an
even number from a program indicates success, and returning an odd
number indicates failure. This obviously conflicts with the
convention of using exit(0) to indicate success.

0 is an even number.
 
K

Keith Thompson

Ben Pfaff said:
0 is an even number.

D'oh!

What I *meant* to say is that returning an even number indicates
failure, and returning an odd number indicates success.
 
K

Keith Thompson

Ben said:
0 is an even number.

D'oh!

What I *meant* to say is that returning an even number indicates
failure, and returning an odd number indicates success.

(Sorry if you see this twice; I initially posted through rr.com, which
is under a UDP.)
 
C

Charlie Gordon

Keith Thompson said:
D'oh!

What I *meant* to say is that returning an even number indicates
failure, and returning an odd number indicates success.

(Sorry if you see this twice; I initially posted through rr.com, which is
under a UDP.)

I saw it only once ;-)
What is a UDP ?
 
R

Richard Heathfield

Charlie Gordon said:

What is a UDP ?

In this context, it stands for "Usenet Death Penalty". It's a sort of mass
plonk, inflicted by news server administrators on an errant peer who is
failing to discipline abusive users.
 
S

Spiros Bousbouras

Spiros Bousbouras wrote:

[...]
How does it follow from the part of the standard that I quoted
that it has to support the two standard forms ? It seems to me
that as long as it satisfies the indented part below the or
meaning the part reading "or in some other implementation-defined
manner" then it can ignore the part above the or. If one of the
two clauses of an or is satisfied then that's good enough , isn't
it ? Although reading the 2nd paragraph of 5.1.2.2.1 perhaps
the intention was that it must always satisfy the part above the
or. If that was the intention then it's not at all clearly phrased.

5.1.2.2.1 specifies requirements for a program, not for an implementation. Note
paragraph 1: "It shall be defined ...". The implementation doesn't define main;
the program does. The implementation's job is to accept any program that meets
the requirements.

Ok , I see it now.
 

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,796
Messages
2,569,645
Members
45,371
Latest member
TroyHursey

Latest Threads

Top