return from main

J

junky_fellow

Guys,

Can I return 0, from main() ? Is this equivalent to
exit(EXIT_SUCCESS) ?

thanks for any help...
 
R

Richard Heathfield

(e-mail address removed) said:
Guys,

Can I return 0, from main() ?
Yes.

Is this equivalent to exit(EXIT_SUCCESS) ?

Yes in practice. In theory, EXIT_SUCCESS and 0 both represent successful
termination but the Standard doesn't forbid them from having different
values and representing different kinds of success! (I don't know of any
implementations that distinguish between them in this way, and it is
likely that there are no such implementations.)
 
K

Keith Thompson

Richard Heathfield said:
(e-mail address removed) said:

Yes in practice. In theory, EXIT_SUCCESS and 0 both represent successful
termination but the Standard doesn't forbid them from having different
values and representing different kinds of success! (I don't know of any
implementations that distinguish between them in this way, and it is
likely that there are no such implementations.)

Obscure exceptions: recursive calls to main() and atexit()-registered
functions that refer to local variables declared in main().
 
E

Eric Sosman

Guys,

Can I return 0, from main() ? Is this equivalent to
exit(EXIT_SUCCESS) ?

thanks for any help...

According to Google Groups, you (or someone using your
alias) have been participating in comp.lang.c since February
of 2004. Since you are still asking basic, first-ten-days
questions after more than four and a half years, I suspect
your abilities lie elsewhere than in computer programming
and I urge you to seek a different sphere of activity.

Or just to stop trolling.
 
J

junky_fellow

According to Google Groups, you (or someone using your
alias) have been participating in comp.lang.c since February
of 2004. Since you are still asking basic, first-ten-days
questions after more than four and a half years, I suspect
your abilities lie elsewhere than in computer programming
and I urge you to seek a different sphere of activity.

Or just to stop trolling.

First of all, Sorry, for asking the similar and such basic questions
again and again.

The reason why I asked this question is because I was not able to
undertand the following lines (mentioned in n1124.pdf at page 13.

"If the return type of the main function is a type compatible with
int, 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;10) reaching the } that
terminates the
main function returns a value of 0. If the return type is not
compatible with int, the
termination status returned to the host environment is unspecified."

The wordings are really confusing. Whenever, I read these lines, I
endup in one or other kind of confusion.
Still, the meaning is unclear to me.
 
R

Richard Heathfield

(e-mail address removed) said:

The reason why I asked this question is because I was not able to
undertand the following lines (mentioned in n1124.pdf at page 13.

"If the return type of the main function is a type compatible with
int, 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;10) reaching the } that
terminates the
main function returns a value of 0. If the return type is not
compatible with int, the
termination status returned to the host environment is unspecified."

The wordings are really confusing. Whenever, I read these lines, I
endup in one or other kind of confusion.
Still, the meaning is unclear to me.

Fortunately, it doesn't matter, and you don't need to understand them. It's
great if you can, but it's not essential, provided you follow this
pattern:

1) always define main as either:

(a) int main(void)

or:

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

and:

2) always return either 0, EXIT_SUCCESS, or EXIT_FAILURE from main.

By the time those two simple rules let you down[1], you'll very likely be
an expert C programmer working on an embedded system, and you'll be able
to consult your system documentation to work out what to do.

[1] ...which they will never do, on conforming hosted implementations...
 
M

Mark Bluemel

The reason why I asked this question is because I was not able to
undertand the following lines (mentioned in n1124.pdf at page 13.

If I reformat and comment, does it help?
"If the return type of the main function is a type compatible with
int,

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;

i.e. return(x) in main is equivalent to exit(x)
(in the initial call - recursive calls are, naturally, different)
reaching the } that terminates the main function returns
a value of 0.

i.e. dropping off the bottom of main() is equivalent to exit(0)
If the return type is not compatible with int, the
termination status returned to the host environment is unspecified."

That should be clear.

(I do wonder whether you should really be spending much time on
reading the standard - a good reference text may be much more useful
to you.)
 
K

Keith Willis

1) always define main as either:

(a) int main(void)

or:

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

Shudder! I am well aware that C != C++, but if one inadvertantly uses
form (a) in "that other froup down the hall", they all start foaming
at the mouth, so because I have to use both languages these days, I
have made something of a point never to use that form :)

(See http://www.research.att.com/~bs/sibling_rivalry.pdf section 2.4,
or just search in that document for the word "abomination"!)
 
R

Richard Heathfield

Keith Willis said:
Shudder! I am well aware that C != C++, but if one inadvertantly uses
form (a) in "that other froup down the hall", they all start foaming
at the mouth, so because I have to use both languages these days, I
have made something of a point never to use that form :)

I always use int main(void) for no-args programs, even in C++. Watching C++
programmers foaming at the mouth is good for the soul.
 
P

Philip Potter

Keith said:
Shudder! I am well aware that C != C++, but if one inadvertantly uses
form (a) in "that other froup down the hall", they all start foaming
at the mouth, so because I have to use both languages these days, I
have made something of a point never to use that form :)

For code which will be compiled as either C or C++ (including many
headers), it is far more desirable to use f(void); because in C++
f(void) is identical semantically to f(), but in C f() has a different
meaning to f(void) and f() will supress a lot of useful compiler warnings.

If you're only writing C++, do what you like. If you're writing which
will be compiled as C, then always use C prototypes.
 
S

Spiros Bousbouras

Shudder! I am well aware that C != C++, but if one inadvertantly uses
form (a) in "that other froup down the hall", they all start foaming
at the mouth, so because I have to use both languages these days, I
have made something of a point never to use that form :)

If one does not need argc and argv in main() I think it's a good
idea to declare it as int main(void) ; it leads to self-documenting
code.
(Seehttp://www.research.att.com/~bs/sibling_rivalry.pdfsection 2.4,
or just search in that document for the word "abomination"!)
From the PDF document:

I abandoned the use of void as an argument type
meaning ''no arguments'' after Dennis Ritchie and
Doug McIlroy strongly condemned it as ''an abomination.''
Instead, I adopted the obvious notation for taking no
arguments, an empty pair of parentheses.
For example:
int f (void ); // error: abomination
int g (); // g takes no argument

Does anyone know where they condemnded it ?
 
S

Spiros Bousbouras

First of all, Sorry, for asking the similar and such basic questions
again and again.

The reason why I asked this question is because I was not able to
undertand the following lines (mentioned in n1124.pdf at page 13.

"If the return type of the main function is a type compatible with
int, 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;10) reaching the } that
terminates the
main function returns a value of 0. If the return type is not
compatible with int, the
termination status returned to the host environment is unspecified."

The wordings are really confusing. Whenever, I read these lines, I
endup in one or other kind of confusion.
Still, the meaning is unclear to me.

The return type of main() is implementation defined. So it
says that if in the implementation you're working with main()
has a return type which is compatible with int then reaching
the end of main() returns the value 0. What "compatible type"
means is defined elsewhere in the standard. On the other hand
if the return type of main() is not compatible with int then
in the absence of an explicit return followed by an expression,
the value returned to the environment is unspecified. The meaning
of "unspecified" is also defined in the standard.
 
J

junky_fellow

(e-mail address removed) said:

<snip>




The reason why I asked this question is because I was not able to
undertand the following lines (mentioned in n1124.pdf at page 13.
"If the return type of the main function is a type compatible with
int, 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;10) reaching the } that
terminates the
main function returns a value of 0. If the return type is not
compatible with int, the
termination status returned to the host environment is unspecified."
The wordings are really confusing. Whenever, I read these lines, I
endup in one or other kind of confusion.
Still, the meaning is unclear to me.

Fortunately, it doesn't matter, and you don't need to understand them. It's
great if you can, but it's not essential, provided you follow this
pattern:

1) always define main as either:

(a) int main(void)

or:

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

and:

2) always return either 0, EXIT_SUCCESS, or EXIT_FAILURE from main.

By the time those two simple rules let you down[1], you'll very likely be
an expert C programmer working on an embedded system, and you'll be able
to consult your system documentation to work out what to do.

[1] ...which they will never do, on conforming hosted implementations...

Thanks everyone for your help. Now, the meaning is quite clear to me.
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.
ie return form main is equivalent to calling exit with the value
returned by the main as its argument and this return will bring the
program control to the } and return the value 0. I was confused that
first it says that return value is the argument to the exit call and
later it says that value returned is 0.

Perhaps, if they would have used "Reaching" instead of "reaching", it
would have been easier for the readers to undertsnat it as follows:

"If the return type of the main function is a type compatible with
int, 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."
 
K

Keith Willis

I abandoned the use of void as an argument type
meaning ''no arguments'' after Dennis Ritchie and
Doug McIlroy strongly condemned it as ''an abomination.''
Instead, I adopted the obvious notation for taking no
arguments, an empty pair of parentheses.
For example:
int f (void ); // error: abomination
int g (); // g takes no argument

Does anyone know where they condemnded it ?

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

Mark Bluemel

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]
 
J

James Kuyper

The reason why I asked this question is because I was not able to
undertand the following lines (mentioned in n1124.pdf at page 13.

"If the return type of the main function is a type compatible with
int, 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;

In other words, your program's true start point isn't really main(). The
start-up code performs whatever processing is needed prior to calling
main(), such as setting up the argv array. Then it acts as if it were
compiled from C code that contains either the line

exit(main());

or

exit(main(argc, argv));

or whatever other interfaces to main that it supports.

If you think about it this way, I hope that it's obvious why 'return x;'
is equivalent to 'exit(x);' only in the initial call to main(), and not
in any recursive calls. However, recursive calls to main() are such a
bizarre thing to do that you ordinarily wouldn't have any reason to use
them, particular if you want to compile the same code in C++, where they
are not allowed.
 
K

Keith Thompson

Spiros Bousbouras said:
The return type of main() is implementation defined. So it
says that if in the implementation you're working with main()
has a return type which is compatible with int then reaching
the end of main() returns the value 0. What "compatible type"
means is defined elsewhere in the standard. On the other hand
if the return type of main() is not compatible with int then
in the absence of an explicit return followed by an expression,
the value returned to the environment is unspecified. The meaning
of "unspecified" is also defined in the standard.

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. An implementation *may* support some other type,
but isn't required to do so.

The only alternative I've seen is accepting a return type of void. In
some implementations it's (probably) an explicitly documented
extension, in others it happens to work though it's not guaranteed,
and in yet others it won't work at all (I think the second is most
common).

Even where it's supported, this:
void main(void) { }
is very likely to be equivalent to this:
int main(void) { return 0; }
or, in C99:
int main(void) { }

I can't think of any reason to use "void main" even where it's
supported.

Freestanding (typically embedded) implementations are another matter.
In a freestanding implementation, the type of the program's entry
point, and even its name, are entirely implementation-defined. You
just have to use whatever the implementation supports.
 
C

Charlie Gordon

James Kuyper said:
In other words, your program's true start point isn't really main(). The
start-up code performs whatever processing is needed prior to calling
main(), such as setting up the argv array. Then it acts as if it were
compiled from C code that contains either the line

exit(main());

or

exit(main(argc, argv));

or whatever other interfaces to main that it supports.

If you think about it this way, I hope that it's obvious why 'return x;'
is equivalent to 'exit(x);'

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.
 

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

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top