Q: recursive call to main, termination of program

Discussion in 'C Programming' started by Seong-Kook Shin, Jan 26, 2005.

  1. 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,
    Seong-Kook Shin, Jan 26, 2005
    #1
    1. Advertising

  2. Seong-Kook Shin

    Chris Torek Guest

    In article <ct7d2e$l1t$>
    Seong-Kook Shin <> 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 (40°39.22'N, 111°50.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.
    Chris Torek, Jan 26, 2005
    #2
    1. Advertising

  3. Seong-Kook Shin

    Richard Bos Guest

    Chris Torek <> wrote:

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


    ISAGN.

    Richard
    Richard Bos, Jan 26, 2005
    #3
  4. Seong-Kook Shin <> 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.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Jan 26, 2005
    #4
  5. 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
    Lawrence Kirby, Jan 26, 2005
    #5
  6. Seong-Kook Shin

    Koollman Guest

    Keith Thompson <> writes:

    > Seong-Kook Shin <> 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
    Koollman, Jan 27, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. J. Campbell

    program termination/memory leaks

    J. Campbell, Sep 11, 2003, in forum: C++
    Replies:
    14
    Views:
    1,037
    J. Campbell
    Sep 13, 2003
  2. R6_2003
    Replies:
    1
    Views:
    526
    Peter van Merkerk
    Oct 23, 2003
  3. Mahmood Ahmad
    Replies:
    3
    Views:
    558
    Mahmood Ahmad
    Feb 22, 2004
  4. ravi
    Replies:
    28
    Views:
    949
    Richard Heathfield
    Sep 26, 2007
  5. Yohan N. Leder
    Replies:
    19
    Views:
    230
    Yohan N. Leder
    Jul 2, 2006
Loading...

Share This Page