Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Q: recursive call to main, termination of program

Reply
Thread Tools

Q: recursive call to main, termination of program

 
 
Seong-Kook Shin
Guest
Posts: n/a
 
      01-26-2005
Hi, I'm reading Steve's "C Programming FAQs" in book version,
and have two question regarding to Q11.16

... Also, a `return' from `main' cannot be expected to work if
data local to main might be needed during cleanup. (Finally
the two forms are obviously not equivalent in a recursive call
to `main').

My questions are

1. Does ANSI standard say that these two forms of
termination of program might be different? I have C99 copy, and
it says..

5.1.2.2.3 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
`main' function returns a value of 0.

If these two forms are equivalent, from when are they equivalent?
ANSI? or C98? or C99?

2. Steve's mention to "recursive call" and C99's "initial call to the main".
I think that it is possible to call main() recursively. But I want
to make it
sure. Is it legal to call main() recursively? And if yes, can
anyone show me
practical (or concise at least) example of it?

3. Above C99 5.1.2.2.3, In "If the return type of the main is a type
compatible
..." Euh? Is it possible that main()'s return type is not compatible
with int?

I thought main should be one of these two forms:
int main(void) { ... }
int main(int argc, char *argv[]) { ... }

I'll thank you for your answers in advance.

Regards,
 
Reply With Quote
 
 
 
 
Chris Torek
Guest
Posts: n/a
 
      01-26-2005
In article <ct7d2e$l1t$(E-Mail Removed)>
Seong-Kook Shin <(E-Mail Removed)> wrote:
>1. Does ANSI standard say that these two forms of
> termination of program might be different? I have C99 copy, and
> it says..
>
> 5.1.2.2.3 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
> `main' function returns a value of 0.
>
> If these two forms are equivalent, from when are they equivalent?
> ANSI? or C98? or C99?


There is something garbled in your quote here.

C89 and C99 differ a bit. If you are an implementor (the guy
writing the C compiler) and are implementing C89, you can implement
the initial call to main as, e.g.:

.global __libc_start
.entry __libc_start
__libc_start:

[ whatever special tricks are required to find argc and argv ]

[ here I assume they wind up in registers v0 and v1, which
are also the return-value registers for integer-valued
functions ]

/* now we just do: exit(main(argc, argv)) */
push v1 /* argv */
push v0 /* argc */
call main /* v0 = main(v0, v1) */
add #8,sp /* undo arguments */

push v0 /* main's return value is the desired exit status */
call exit /* exit(status) */
/* NOTREACHED */
halt /* "just in case" */

.end __libc_start

(you would write this in some kind of assembler language, typically).

Note that this passes main() exactly two arguments, and assumes
that passing two arguments to "int main(void)" is harmless. The
latter is usually true on most machines -- if not, you will need
to have your compiler tell you whether to call the two-argument
main() or the zero-argument main().

In C99, your job as compiler-and-library-writer is harder, because
C99 allows programs to "fall off the end" of main without returning
a value, and have main() act as if it ended with "return 0;" in
that case. That is:

int main(void)
{
}

and:

int main(void)
{
return 0;
}

are 100% identical programs in C99, but very different programs
in C89. You have to invent some mechanism to make this work in
C99.

>2. Steve's mention to "recursive call" and C99's "initial call to the main".
> I think that it is possible to call main() recursively. But I want
>to make it
> sure. Is it legal to call main() recursively? And if yes, can
>anyone show me
> practical (or concise at least) example of it?


Yes, and maybe:

#include <stdio.h>

int main(int argc, char **argv) {
if (argc > 1) {
main(argc - 1, argv + 1);
puts(argv[1]);
}
return 0;
}

>3. Above C99 5.1.2.2.3, In "If the return type of the main is a type
>compatible
> ..." Euh? Is it possible that main()'s return type is not compatible
>with int?
>
> I thought main should be one of these two forms:
> int main(void) { ... }
> int main(int argc, char *argv[]) { ... }
>
>I'll thank you for your answers in advance.


It should indeed be, if you are writing a C program for any hosted
implementation.

Any implementation can, on the other hand, *allow* (but not require)
you to do something else to get some interesting and wanted (or
pointless, or unwanted, or even harmful) non-Standard behavior.
For instance, an implementor could decide that if you write:

double main(void) { }

and compile it, the resulting program will play Chess at grandmaster
level, but if the computer loses, make the computer burst into
flames.

Since Standard C cannot even draw graphics, much less let you play
chess with a display and mouse, this might be a big selling point.
Of course, this is a really bizarre way to do it; it would probably
be wiser, if you are the implementor, to provide non-Standard
<graphics.h>, <mouse.h>, and <chess.h> headers or some such. (The
auxiliary "sore loser" support might perhaps be in <badtemper.h>.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      01-26-2005
Chris Torek <(E-Mail Removed)> wrote:

> (The auxiliary "sore loser" support might perhaps be in <badtemper.h>.)


ISAGN.

Richard
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-26-2005
Seong-Kook Shin <(E-Mail Removed)> writes:
> Hi, I'm reading Steve's "C Programming FAQs" in book version,
> and have two question regarding to Q11.16
>
> ... Also, a `return' from `main' cannot be expected to work if
> data local to main might be needed during cleanup. (Finally
> the two forms are obviously not equivalent in a recursive call
> to `main').
>
> My questions are
>
> 1. Does ANSI standard say that these two forms of
> termination of program might be different? I have C99 copy, and
> it says..
>
> 5.1.2.2.3 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 `main' function returns a value of
> 0.
>
> If these two forms are equivalent, from when are they equivalent?
> ANSI? or C98? or C99?


It says "from the initial call", which excludes recursive calls.

> 2. Steve's mention to "recursive call" and C99's "initial call to the main".
> I think that it is possible to call main() recursively. But I
> want to make it sure. Is it legal to call main() recursively?
> And if yes, can anyone show me practical (or concise at least)
> example of it?


Yes, it's possible to call main recursively in C. <OT>C++ disallows
this.</OT>

There is no practical reason to call main recursively, unless you're
trying to write deliberately obfuscated code. But here's a silly
example:

#include <stdio.h>
int main(int argc, char **argv)
{
if (argc > 1) {
printf("%s ", argv[1]);
main(argc-1, argv+1);
}
else {
printf("\n");
}
return 0;
}

> 3. Above C99 5.1.2.2.3, In "If the return type of the main is a type
> compatible
> ..." Euh? Is it possible that main()'s return type is not compatible
> with int?
>
> I thought main should be one of these two forms:
> int main(void) { ... }
> int main(int argc, char *argv[]) { ... }


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

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Lawrence Kirby
Guest
Posts: n/a
 
      01-26-2005
On Wed, 26 Jan 2005 15:33:33 +0900, Seong-Kook Shin wrote:

> Hi, I'm reading Steve's "C Programming FAQs" in book version,
> and have two question regarding to Q11.16
>
> ... Also, a `return' from `main' cannot be expected to work if
> data local to main might be needed during cleanup. (Finally
> the two forms are obviously not equivalent in a recursive call
> to `main').
>
> My questions are
>
> 1. Does ANSI standard say that these two forms of
> termination of program might be different?


It follows from the fact that when you leave the block in which automatic
variables are defined, e.g. by returning from a function, those variables
cease to exist.

> I have C99 copy, and
> it says..
>
> 5.1.2.2.3 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
> `main' function returns a value of 0.


This has been discussed in the past. There is a case for reading this as
calling exit() at the point (i.e. in the block) that the return statement
exists, but many people, including significantly compiler writers don't.
So just interpret the call to exit() as happening after main() has been
left. That's the likely intent.

> If these two forms are equivalent, from when are they equivalent?
> ANSI? or C98? or C99?
>
> 2. Steve's mention to "recursive call" and C99's "initial call to the
> main".
> I think that it is possible to call main() recursively. But I want
> to make it
> sure. Is it legal to call main() recursively? And if yes, can
> anyone show me
> practical (or concise at least) example of it?


It is supported, but there's no obvious use for it beyond IOCCC contests,
and puzzles such as writing shortest possible programs.

> 3. Above C99 5.1.2.2.3, In "If the return type of the main is a type
> compatible
> ..." Euh? Is it possible that main()'s return type is not compatible
> with int?


An implementation may support other return types. Compilers for Windows
systems seem to have a tendancy to support void as a return type, if you
could repeated use of such a form in their documentation examples as
"support".

> I thought main should be one of these two forms:
> int main(void) { ... }
> int main(int argc, char *argv[]) { ... }



Those are the forms that the standard requires an implementation to
support, it doesn't forbid the implementation from supporting other forms.
What this means is that portable code should use one of these forms, or a
compatible one because other forms have undefined behaviour as far as the
standard is concerned.

Lawrence
 
Reply With Quote
 
Koollman
Guest
Posts: n/a
 
      01-27-2005
Keith Thompson <(E-Mail Removed)> writes:

> Seong-Kook Shin <(E-Mail Removed)> writes:
>
>> 2. Steve's mention to "recursive call" and C99's "initial call to the main".
>> I think that it is possible to call main() recursively. But I
>> want to make it sure. Is it legal to call main() recursively?
>> And if yes, can anyone show me practical (or concise at least)
>> example of it?

>
> Yes, it's possible to call main recursively in C. <OT>C++ disallows
> this.</OT>
>
> There is no practical reason to call main recursively, unless you're
> trying to write deliberately obfuscated code. But here's a silly
> example:
>
> #include <stdio.h>
> int main(int argc, char **argv)
> {
> if (argc > 1) {
> printf("%s ", argv[1]);
> main(argc-1, argv+1);
> }
> else {
> printf("\n");
> }
> return 0;
> }
>


I have found one reason: I was making a shell, and was searching for a
'clean' way of conserving environment while using a kind of 'subshell'
(with the possibility of exporting variables from the subshell to the
main shell)

But I admit it was not the only way, and it was really weird to read
the main without comments...

--
Thomas SAMSON
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Recursive functions Vs Non-recursive functions - performance aspect vamsi C Programming 21 03-09-2009 10:53 PM
Two recursive calls inside of a recursive function n00m C++ 12 03-13-2008 03:18 PM
Does recursive call able to print in same page as main call Yohan N. Leder Perl Misc 19 07-02-2006 11:45 AM
defined? for recursive function call v/s defined? for function call stack Alok Ruby 3 04-13-2006 11:53 AM
Re: Call termination problem Dave Phelps Cisco 3 07-14-2003 09:25 AM



Advertisments