Path: utzoo!attcan!uunet!lll-winken!ames!mailrus!cornell!uw-beaver!mit-eddie!bu-cs!mirror!frog!john From: john@frog.UUCP (John Woods) Newsgroups: comp.lang.c Subject: Re: main() and exit() (was: Strange lint mumblings) Message-ID: <1350@X.UUCP> Date: 12 Jan 89 02:49:00 GMT References: <416@marob.MASA.COM> <11467@dartvax.Dartmouth.EDU> <179@amsdsg.UUCP> <15186@mimsy.UUCP> Distribution: na Organization: Servants of the Great White Frog Lines: 47 Just to pick a couple of nano-nits: In article <15186@mimsy.UUCP>, chris@mimsy.UUCP (Chris Torek) writes: > /* exit.c */ > /* > * I have forgotten the details of atexit, so I am assuming > * that atexit() registers a (void (*)(void)), and returns > * success (0) / failure (nonzero). Correct. > */ > typedef void (*exitfn)(void); > static exitfn exit_functions[32]; This should be 33, since one should be able to register 32 things in addition to the "invisible" stdio flush. > ... > void exit(int code) { > register int i; > > /* > * Call registered atexit functions, in reverse. > * If stdio has registered a cleanup function, it > * will be in slot 0 and therefore called last. > */ I don't have a modern copy of the dpANS in front of me, but I believe that exit is supposed to be reentrant (in case an atexit handler really botches things up and calls exit). Thus, each function should probably be marked as unregistered just before calling it, thusly: > for (i = next_exit_fn; --i >= 0;) > if (exit_functions[i] != NULL) { exitfn holder = exit_functions[i]; exit_functions[i] = NULL; (*holder)(); } > /* now really exit */ > _exit(code); > } > (and even if the dpANS doesn't specify reentrancy, why leave oneself open to easy bugs? Make the program WORK to get stuck in an infinite loop :-) Other than that, thanks again to Chris for yet another excellent article. -- John Woods, Charles River Data Systems, Framingham MA, (508) 626-1101 ...!decvax!frog!john, john@frog.UUCP, ...!mit-eddie!jfw, jfw@eddie.mit.edu Go be a `traves wasswort. - Doug Gwyn