How can exit(n) give a function the return value?

Discussion in 'C Programming' started by lovecreatesbeauty, Mar 7, 2006.

  1. Hello experts,

    Is the following code snippet legal? If it is, how can exit() do the
    keyword return a favor and give a return value to the main function?

    Can a function call (or only this exit(n)) statement provide both
    function call and return features of the C programming language?

    /* headers omitted */
    int main (void)
    {
    exit(0); /* instead of `return 0;' */
    }

    Sincerely,

    lovecreatesbeauty
    lovecreatesbeauty, Mar 7, 2006
    #1
    1. Advertising

  2. lovecreatesbeauty

    Ian Collins Guest

    lovecreatesbeauty wrote:
    > Hello experts,
    >
    > Is the following code snippet legal? If it is, how can exit() do the
    > keyword return a favor and give a return value to the main function?
    >
    > Can a function call (or only this exit(n)) statement provide both
    > function call and return features of the C programming language?
    >
    > /* headers omitted */
    > int main (void)
    > {
    > exit(0); /* instead of `return 0;' */
    > }
    >

    I guess _exit(0) is closer to return(0), exit does some clean-up
    processing before terminating.

    Both return the status to the caller (if there is one). Exactly how
    this magic is performed would be platform specific.

    The exit functions differ form return in that they will terminate the
    program no matter where they are called.

    --
    Ian Collins.
    Ian Collins, Mar 7, 2006
    #2
    1. Advertising

  3. lovecreatesbeauty

    Eric Sosman Guest

    lovecreatesbeauty wrote:
    > Hello experts,
    >
    > Is the following code snippet legal? If it is, how can exit() do the
    > keyword return a favor and give a return value to the main function?
    >
    > Can a function call (or only this exit(n)) statement provide both
    > function call and return features of the C programming language?
    >
    > /* headers omitted */
    > int main (void)
    > {
    > exit(0); /* instead of `return 0;' */
    > }


    First: Yes, the code is legal. But exit() has nothing
    to do with the `return' keyword, and it does not supply a
    return value for the main() function. When you call exit(),
    main() does not return at all: exit() terminates the program
    without ever returning.

    Consider a slightly more complicated program:

    #include <stdio.h>
    #include <stdlib.h>
    static void func(void);
    int main(void) {
    puts ("Before func()");
    func();
    puts ("After func()");
    return EXIT_SUCCESS;
    }
    static void func(void) {
    exit(EXIT_FAILURE);
    }

    Clearly, exit() does not return a value from func(). If it
    caused func() to return, main() would resume right after the
    call to func() and would proceed to the subsequent puts() --
    which we know does not occur. Furthermore, func() is a `void'
    function and cannot return any value at all! So a little
    thought reveals that exit() and `return' are unrelated, even
    though both (in proper context) can cause program termination.

    --
    Eric Sosman
    lid
    Eric Sosman, Mar 7, 2006
    #3
  4. lovecreatesbeauty

    Micah Cowan Guest

    "lovecreatesbeauty" <> writes:

    > Hello experts,
    >
    > Is the following code snippet legal? If it is, how can exit() do the
    > keyword return a favor and give a return value to the main function?
    >
    > Can a function call (or only this exit(n)) statement provide both
    > function call and return features of the C programming language?
    >
    > /* headers omitted */
    > int main (void)
    > {
    > exit(0); /* instead of `return 0;' */
    > }


    Only exit() can do this. It takes advantage of specific knowledge of
    how to exit and provide a result code to the operating system; so
    nobody would be able to simply write their own (portably).

    exit() is provided mostly so that you can exit your program
    /suddenly/, perhaps from somewhere deeply nested within your
    program. It is probably most frequently encountered as a response to
    an error condition that is encountered by the program.

    As a matter of style, I would never call exit() from main, though: it
    would provide no advantages over the return keyword.
    Micah Cowan, Mar 7, 2006
    #4
  5. Eric Sosman wrote:
    > lovecreatesbeauty wrote:
    > > Hello experts,
    > >
    > > Is the following code snippet legal? If it is, how can exit() do the
    > > keyword return a favor and give a return value to the main function?
    > >
    > > Can a function call (or only this exit(n)) statement provide both
    > > function call and return features of the C programming language?
    > >
    > > /* headers omitted */
    > > int main (void)
    > > {
    > > exit(0); /* instead of `return 0;' */
    > > }

    >


    <snip>

    > static void func(void) {
    > exit(EXIT_FAILURE);
    > }
    >


    <snip>

    > Furthermore, func() is a `void'
    > function and cannot return any value at all!


    Thank you.

    But in my sample code int main(); requires a return value, and a
    `return n' statement following `exit( 0)' can not be reached of course.

    Does ANSI C allow a default return value for functions without return
    statement? I am anxious on it.
    lovecreatesbeauty, Mar 7, 2006
    #5
  6. lovecreatesbeauty wrote:
    > ... in my sample code int main(); requires a return value,


    main() never _requires_ a return value. [Actually, there is one
    exception
    in that if main is being called recursively in C90, and the calling
    function
    uses the return value, then the behaviour is undefined.]

    > and a `return n' statement following `exit( 0)' can not be reached of course.


    You don't need one. If you're compiler refuses to compile the code
    because your main finishes on exit and not return, then you have
    failed to invoke it in conforming mode.

    Your compiler may issue warnings, but it can issue warnings for
    _any_ reason. It is up to the programmer to decipher wether a
    warning warants action or not.

    > Does ANSI C allow a default return value for functions without return
    > statement?


    C90 and C99 both allow non-void functions to return to the caller
    without
    explicitly returning a value (i.e. without a return statement,) so long
    as
    the calling function doesn't attempt to use the value...

    int foo() { } /* no return value */
    void bah() { foo(); } /* fine! */

    [C++ is different in that regard.]

    The main function itself has always been further special cased. In C99,
    falling off main (reaching the end without a return) will result in a
    value
    of 0 being returned.

    In C90, if the first call to main returns without returning a value,
    then
    the 'status' returned to the host is undefined, but the program is
    otherwise well behaved.

    > I am anxious on it.


    Then get yourself the last public draft of the C standard and read it
    for yourself. ;-)

    --
    Peter
    Peter Nilsson, Mar 7, 2006
    #6
  7. lovecreatesbeauty

    Jordan Abel Guest

    On 2006-03-07, Ian Collins <> wrote:
    > lovecreatesbeauty wrote:
    >> Hello experts,
    >>
    >> Is the following code snippet legal? If it is, how can exit() do the
    >> keyword return a favor and give a return value to the main function?
    >>
    >> Can a function call (or only this exit(n)) statement provide both
    >> function call and return features of the C programming language?
    >>
    >> /* headers omitted */
    >> int main (void)
    >> {
    >> exit(0); /* instead of `return 0;' */
    >> }
    >>

    > I guess _exit(0) is closer to return(0), exit does some clean-up
    > processing before terminating.


    So does return from main. The difference is in whether automatic
    variables declared in main are avaible to atexit handlers.

    > Both return the status to the caller (if there is one). Exactly how
    > this magic is performed would be platform specific.
    >
    > The exit functions differ form return in that they will terminate the
    > program no matter where they are called.
    Jordan Abel, Mar 7, 2006
    #7
  8. lovecreatesbeauty

    Ben Pfaff Guest

    "lovecreatesbeauty" <> writes:

    > Is the following code snippet legal? If it is, how can exit() do the
    > keyword return a favor and give a return value to the main function?


    You seem to be under the impression exit() somehow causes a
    return from main(). That is one possible implementation. But a
    more common implementation is that a return from main() causes
    exit() to be returned. That is, some implementations effectively
    start from a function called, say, _start, which might be written
    this way:

    int
    _start (int argc, char *argv[])
    {
    exit (main (argc, argv));
    }
    --
    "I ran it on my DeathStation 9000 and demons flew out of my nose." --Kaz
    Ben Pfaff, Mar 7, 2006
    #8
  9. lovecreatesbeauty

    Chris Torek Guest

    In article <>
    Ben Pfaff <> wrote:
    >... a more common implementation is that a return from main() causes
    >exit() to be returned.


    Presumably you mean "causes exit() to be called" here:

    >That is, some implementations effectively start from a function
    >called, say, _start, which might be written this way:
    >
    >int
    >_start (int argc, char *argv[])
    >{
    > exit (main (argc, argv));
    >}


    And in fact, most real-world implementations have code much like
    this, although _start or __startup or whatever it is named tends
    to be a bit more complicated. (In many cases it has to compute
    argc and/or argv somehow, load libraries, hook up the standard I/O
    streams and otherwise initialize the C runtime support, and so on.)

    The fact that someone else wrote the startup code, which calls
    exit() with whatever your main() returns, is why you should return
    a value from your main(). C99 allows you to omit the return value
    (forcing the compiler to supply one for you in this case), but C90
    does not, and in any case, why should you give up your power to
    return a useful value?
    --
    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, Mar 7, 2006
    #9
  10. In article <>,
    lovecreatesbeauty <> wrote:

    >Is the following code snippet legal? If it is, how can exit() do the
    >keyword return a favor and give a return value to the main function?


    It doesn't. If you call exit(), main() doesn't return, so it doesn't
    matter that it hasn't got a return statement.

    -- Richard
    Richard Tobin, Mar 7, 2006
    #10
  11. lovecreatesbeauty

    pemo Guest

    Jordan Abel wrote:
    > On 2006-03-07, Ian Collins <> wrote:
    >> lovecreatesbeauty wrote:
    >>> Hello experts,
    >>>
    >>> Is the following code snippet legal? If it is, how can exit() do the
    >>> keyword return a favor and give a return value to the main function?
    >>>
    >>> Can a function call (or only this exit(n)) statement provide both
    >>> function call and return features of the C programming language?
    >>>
    >>> /* headers omitted */
    >>> int main (void)
    >>> {
    >>> exit(0); /* instead of `return 0;' */
    >>> }
    >>>

    >> I guess _exit(0) is closer to return(0), exit does some clean-up
    >> processing before terminating.

    >
    > So does return from main. The difference is in whether automatic
    > variables declared in main are avaible to atexit handlers.


    I read that initially as "automatic variables are available to atexit
    handlers"

    Wrong - right?


    --
    ==============
    *Not a pedant*
    ==============
    pemo, Mar 7, 2006
    #11
  12. lovecreatesbeauty

    Richard Bos Guest

    "pemo" <> wrote:

    > Jordan Abel wrote:
    > > On 2006-03-07, Ian Collins <> wrote:
    > >> I guess _exit(0) is closer to return(0), exit does some clean-up
    > >> processing before terminating.

    > >
    > > So does return from main. The difference is in whether automatic
    > > variables declared in main are avaible to atexit handlers.

    >
    > I read that initially as "automatic variables are available to atexit
    > handlers"
    >
    > Wrong - right?


    And there's the rub.

    If the program is ended through exit(), all auto objects in main() still
    exist when the atexit handlers are called. One of the handlers could
    refer to such an object - for example, if a global pointer had been set
    to point at one of them.

    If the program is ended through a return from main(), all auto objects
    in main() will already have disappeared when the atexit handlers are
    called. If a handler dereferences a pointer to such an ex-object, your
    data could be pushing up the daisies.

    Whether anyone sane will ever write an atexit handler that depends on
    this difference - well, that's another question.

    Richard
    Richard Bos, Mar 7, 2006
    #12
  13. lovecreatesbeauty

    Eric Sosman Guest

    Richard Bos wrote:
    >
    > If the program is ended through a return from main(), all auto objects
    > in main() will already have disappeared when the atexit handlers are
    > called. If a handler dereferences a pointer to such an ex-object, your
    > data could be pushing up the daisies.
    >
    > Whether anyone sane will ever write an atexit handler that depends on
    > this difference - well, that's another question.


    The problem can occur even without an explicit atexit()
    handler:

    int main(void) {
    char buffer[16384];
    setvbuf (stdout, buffer, _IOFBF, sizeof buffer);
    ...
    return 0; /* woops! */
    }

    --
    Eric Sosman
    lid
    Eric Sosman, Mar 7, 2006
    #13
  14. lovecreatesbeauty

    Robin Haigh Guest

    "Richard Bos" <> wrote in message
    news:4all.nl...
    > "pemo" <> wrote:
    >
    > > Jordan Abel wrote:
    > > > On 2006-03-07, Ian Collins <> wrote:
    > > >> I guess _exit(0) is closer to return(0), exit does some clean-up
    > > >> processing before terminating.
    > > >
    > > > So does return from main. The difference is in whether automatic
    > > > variables declared in main are avaible to atexit handlers.

    > >
    > > I read that initially as "automatic variables are available to atexit
    > > handlers"
    > >
    > > Wrong - right?

    >
    > And there's the rub.
    >
    > If the program is ended through exit(), all auto objects in main() still
    > exist when the atexit handlers are called. One of the handlers could
    > refer to such an object - for example, if a global pointer had been set
    > to point at one of them.
    >
    > If the program is ended through a return from main(), all auto objects
    > in main() will already have disappeared when the atexit handlers are
    > called. If a handler dereferences a pointer to such an ex-object, your
    > data could be pushing up the daisies.
    >
    > Whether anyone sane will ever write an atexit handler that depends on
    > this difference - well, that's another question.



    I can see people doing this:

    #include <stdlib.h>

    char **pa;

    void cleanup(void) {
    int i;
    for ( i=0 ; i<10 ; i++ )
    free(pa);
    }

    int main(void){
    int i;
    char *a[10];
    for ( i=0 ; i<10 ; i++ ) {
    a = malloc(whatever);
    }
    pa = a;
    atexit(cleanup);
    /* etc */
    }

    You aren't going to see what's wrong with this unless you've heard about the
    issue. I certainly wouldn't call it insane. It's a nasty little trap.

    One way to steer cleer of it is always to terminate using exit and never
    return from main (though of course that leaves a hostage to fortune for
    future maintenance)

    --
    RSH
    Robin Haigh, Mar 7, 2006
    #14
  15. Peter Nilsson wrote:
    > lovecreatesbeauty wrote:
    > > ... in my sample code int main(); requires a return value,

    >
    > main() never _requires_ a return value. [Actually, there is one
    > exception in that if main is being called recursively in C90, and the calling
    > function uses the return value, then the behaviour is undefined.]
    >


    Perhaps I did not make it clear in my reply, sorry to bring this
    misunderstanding. I do not know whether the entry point function main
    needs a return value or not up to now. But I meant the prototype:

    int main();

    indicated that the function call expression had a value. There was no
    return statement inside the function body. In my original post, there
    is only one exit(0) call inside the function body. So how can the
    semantics of the prototype be fulfilled?

    I can understand this one: void f1(void) { exit(0); }
    I can not understand this one: int f2(void) { exit(0); }

    I read Richard Tobin's reply and I think I understand it. In my
    original sample code, the int main(); function does not return, and it
    does not mind whether it get a return value. As well as the discard of
    the return value of a function like int main();, no return value is not
    illegal. Do I understand it correct?

    Thank all of you.
    lovecreatesbeauty, Mar 7, 2006
    #15
  16. lovecreatesbeauty

    Ben Pfaff Guest

    Chris Torek <> writes:

    > In article <>
    > Ben Pfaff <> wrote:
    >>... a more common implementation is that a return from main() causes
    >>exit() to be returned.

    >
    > Presumably you mean "causes exit() to be called" here:


    Yes, thank you for the correction.
    --
    "I don't have C&V for that handy, but I've got Dan Pop."
    --E. Gibbons
    Ben Pfaff, Mar 7, 2006
    #16
  17. lovecreatesbeauty

    Robin Haigh Guest

    "lovecreatesbeauty" <> wrote in message
    news:...
    >
    > Peter Nilsson wrote:
    > > lovecreatesbeauty wrote:
    > > > ... in my sample code int main(); requires a return value,

    > >
    > > main() never _requires_ a return value. [Actually, there is one
    > > exception in that if main is being called recursively in C90, and the

    calling
    > > function uses the return value, then the behaviour is undefined.]
    > >

    >
    > Perhaps I did not make it clear in my reply, sorry to bring this
    > misunderstanding. I do not know whether the entry point function main
    > needs a return value or not up to now. But I meant the prototype:
    >
    > int main();
    >
    > indicated that the function call expression had a value. There was no
    > return statement inside the function body. In my original post, there
    > is only one exit(0) call inside the function body. So how can the
    > semantics of the prototype be fulfilled?
    >
    > I can understand this one: void f1(void) { exit(0); }
    > I can not understand this one: int f2(void) { exit(0); }
    >
    > I read Richard Tobin's reply and I think I understand it. In my
    > original sample code, the int main(); function does not return, and it
    > does not mind whether it get a return value. As well as the discard of
    > the return value of a function like int main();, no return value is not
    > illegal. Do I understand it correct?


    Yes. In general, the flow of control in a program depends on the input
    data, and can't be determined at compile time.(*) So there isn't much point
    in requiring that an int function must contain a return statement, because
    you can't tell whether any of the return statements will ever be reached.

    At run time, only the statements executed matter.

    (*) In fact some algorithms have theoretically unknown behaviour even
    without any input data

    --
    RSH
    Robin Haigh, Mar 7, 2006
    #17
  18. lovecreatesbeauty

    Jordan Abel Guest

    On 2006-03-07, lovecreatesbeauty <> wrote:
    >
    > Peter Nilsson wrote:
    >> lovecreatesbeauty wrote:
    >> > ... in my sample code int main(); requires a return value,

    >>
    >> main() never _requires_ a return value. [Actually, there is one
    >> exception in that if main is being called recursively in C90, and the calling
    >> function uses the return value, then the behaviour is undefined.]
    >>

    >
    > Perhaps I did not make it clear in my reply, sorry to bring this
    > misunderstanding. I do not know whether the entry point function main
    > needs a return value or not up to now. But I meant the prototype:
    >
    > int main();
    >
    > indicated that the function call expression had a value. There was no
    > return statement inside the function body. In my original post, there
    > is only one exit(0) call inside the function body. So how can the
    > semantics of the prototype be fulfilled?


    Some of the people in this group have radical ideas about the semantics
    of main() in particular. I think Peter Nilsson's claim (which I disagree
    with) is that even without an exit statement, main doesn't need to
    return a value, since main's caller is outside the scope of the C
    standard.

    > I can understand this one: void f1(void) { exit(0); }
    > I can not understand this one: int f2(void) { exit(0); }


    Well - funny you ask. Due to yet another K&R holdover, int functions
    don't have to return a value - "return;" or reaching the final right
    brace is valid. However, the "returned value" cannot be used by any
    caller.

    >
    > I read Richard Tobin's reply and I think I understand it. In my
    > original sample code, the int main(); function does not return, and it
    > does not mind whether it get a return value. As well as the discard of
    > the return value of a function like int main();, no return value is
    > not illegal. Do I understand it correct?
    >
    > Thank all of you.
    >
    Jordan Abel, Mar 7, 2006
    #18
  19. lovecreatesbeauty

    Ben Pfaff Guest

    Jordan Abel <> writes:

    > Due to yet another K&R holdover, int functions don't have to
    > return a value - "return;" or reaching the final right brace is
    > valid.


    "return;" in a function returning int is no longer allowed in
    C99:

    6.8.6.4 The return statement
    Constraints

    1 A return statement with an expression shall not appear in a
    function whose return type is void. A return statement
    without an expression shall only appear in a function whose
    return type is void.

    --
    "You call this a *C* question? What the hell are you smoking?" --Kaz
    Ben Pfaff, Mar 7, 2006
    #19
  20. "Robin Haigh" <> writes:
    [...]
    > Yes. In general, the flow of control in a program depends on the input
    > data, and can't be determined at compile time.(*) So there isn't much point
    > in requiring that an int function must contain a return statement, because
    > you can't tell whether any of the return statements will ever be reached.

    [...]

    Theoretically, the language could require that there be a return
    statement along all possible execution paths. For example:

    int foo(void)
    {
    if (something) {
    /* A */
    }
    else {
    /* B */
    }
    /* C */
    }

    If there's a return statement at C, *or* if there are return
    statements at both A and B, then one of them will always be executed;
    otherwise the compiler can't prove that foo() can never reach the
    closing brace without executing a return. (There are cases where a
    function will never reach the closing brace but the compiler can't
    prove it.)

    Some compilers do this analysis and issue a warning such as "control
    reaches end of non-void function". With some effort, the standard
    could require all compilers to do this analysis, and make it a
    constraint violation if the check fails. (I'm not necessariliy
    advocating such change in the standard, just saying that it would be
    possible.)

    --
    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, Mar 7, 2006
    #20
    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. QQ
    Replies:
    5
    Views:
    521
    Jonathan Adams
    May 10, 2005
  2. Yujo
    Replies:
    2
    Views:
    404
    Gabriel Genellina
    Apr 10, 2007
  3. Replies:
    2
    Views:
    444
    sloan
    Jun 17, 2008
  4. jacob navia
    Replies:
    3
    Views:
    553
    Nick Keighley
    Feb 24, 2010
  5. Keith Thompson
    Replies:
    10
    Views:
    687
    Tim Rentsch
    Mar 3, 2010
Loading...

Share This Page