[comp.lang.c] return in main is *not* equivalent to exit

martin@mwtech.UUCP (Martin Weitzel) (07/04/90)

In article <4238@jato.Jpl.Nasa.Gov> kaleb@mars.UUCP (Kaleb Keithley) writes:
>
>Furthermore, on p. 164 (Ibid.) [K&R2] it is stated:
>
>Within main, return expr is equivalent to exit(expr).  exit has the
>advantage...

K&R2 is right?

Nearly right! I'll never forget the day when I tracked down what
seemed to be a really wierd problem in some printer driving code
to the following (still buggy!) program:

	#include <stdio.h>
	int main(argc, argv)
		int argc; char **argv; /* OK so, Chris? :-) */
	{
		char buffer[BUFSIZ];
		setbuf(stdout, buffer);
		........ /* some code which produced output */
		return 0;
	}

Note that the bug could be eliminated by replacing `return 0;'
with `exit (0);'. Well, after that the cause for this problem
became obvious to me ... of course, all of you readers out there
in net-world allready know what the problem is, don't you :-)
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83

darcy@druid.uucp (D'Arcy J.M. Cain) (07/05/90)

In article <833@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
>Nearly right! I'll never forget the day when I tracked down what
>seemed to be a really wierd problem in some printer driving code
>to the following (still buggy!) program:
>
>	#include <stdio.h>
>	int main(argc, argv)
>		int argc; char **argv; /* OK so, Chris? :-) */
>	{
>		char buffer[BUFSIZ];
>		setbuf(stdout, buffer);
>		........ /* some code which produced output */
>		return 0;
>	}
>
>Note that the bug could be eliminated by replacing `return 0;'
>with `exit (0);'. Well, after that the cause for this problem
>became obvious to me ... of course, all of you readers out there
>in net-world allready know what the problem is, don't you :-)

You didn't say but I assume that the problem was garbage output at the
end of the program?  Other ways to fix this:
    declare buffer as static
    flush buffers before returning
    drop the setbuf call

The same sort of thing could happen if you malloc space for the buffer and
then free it when you are finished doing output.

-- 
D'Arcy J.M. Cain (darcy@druid)     |   Government:
D'Arcy Cain Consulting             |   Organized crime with an attitude
West Hill, Ontario, Canada         |
(416) 281-6094                     |

6sigma2@polari.UUCP (Brian Matthews) (07/07/90)

In article <833@mwtech.UUCP> martin@mwtech.UUCP (Martin Weitzel) writes:
|I'll never forget the day when I tracked down what
|seemed to be a really wierd problem in some printer driving code
|to the following (still buggy!) program:
|
|	#include <stdio.h>
|	int main(argc, argv)
|		int argc; char **argv; /* OK so, Chris? :-) */
|	{
|		char buffer[BUFSIZ];
|		setbuf(stdout, buffer);
|		........ /* some code which produced output */
|		return 0;
|	}
|
|Note that the bug could be eliminated by replacing `return 0;'
|with `exit (0);'. Well, after that the cause for this problem
|became obvious to me...

I don't have my copy of the standard here, but I believe the section
on setvbuf (which also applies to setbuf) says something about the
buffer having to exist as long as the stream is open.  You don't
close stdout before the return, so the automatic buffer is destroyed
before the stream is closed.  The program doesn't conform to the
standard, so it's NOT an example of a difference between return
and exit (as far as the standard is concerned).

And yes, this sort of thing can be tough to debug.  Usually when
I see an automatic array or structure, it screams to be looked at
to make sure it can't be used outside of the block or its children.
-- 
Brian L. Matthews	blm@6sceng.UUCP

edward@runxtsa.runx.oz.au (Edward Birch) (07/11/90)

>	#include <stdio.h>
>	int main(argc, argv)
>		int argc; char **argv; /* OK so, Chris? :-) */
>	{
>		char buffer[BUFSIZ];
>		setbuf(stdout, buffer);
>		........ /* some code which produced output */
>		return 0;
>	}
>
>Note that the bug could be eliminated by replacing `return 0;'
>with `exit (0);'. Well, after that the cause for this problem
>became obvious to me ... of course, all of you readers out there
>in net-world allready know what the problem is, don't you :-)

You will find that the real problem is that some how the return address
for main has been corrupted.

As far as I am concerned return <expr> and exit(<expr>); are the same
thing for "main", in the general case.

Please note that "main" is a routine in it's own right and can be called
recursively! Hence in the recurive case exit(<expr>) is explicit.
It means terminate now, whereas return <expr>; may not.
I think this is what K&R meant at the time.

Secondly "main" as the first routine of a program is only a convention
most compilers have some other entry point like "start" which sets up
the arguments and environment variables etc for "main" and then calls
"main" the object code  for these modules is stored in /lib/crt0.o .

Edward Birch

Telex: 10713856 BRHT

UUCP:   seismo!munnari!runx.oz!edward   ACSnet:  edward@runx.oz
ARPA:   edward%runx.oz@seismo.css.gov   CSNET:   edward@runx.oz