Path: utzoo!utgpu!watmath!att!rutgers!ucsd!usc!samsung!munnari.oz.au!csc!bdm659 From: bdm659@csc.anu.oz Newsgroups: comp.lang.c Subject: Re: void main() (Was: (* func)(fred, bert)) Message-ID: <1015.2563d6e0@csc.anu.oz> Date: 17 Nov 89 10:01:04 GMT References: <2387@stl.stc.co.uk> <744@lakart.UUCP> <0175@sheol.UUCP> <11592@smoke.BRL.MIL> <7733@cdis-1.uucp> Organization: Computer Services, Australian National University Lines: 49 In article <7733@cdis-1.uucp>, tanner@cdis-1.uucp (Dr. T. Andrews) writes: > [[The question is: why is it wrong to declare main() as void, instead of > int, even though he program is terminated by calling exit() explicitely?]] > > I should like to hear details of a case where the code will not > work. It seems ridiculous to declare un-portable the results of a > void-vs-int return linkage which is never made, and I should like > to hear of an implementation where this actually fails. > > If no real-world example is available, I should be almost as > satisfied with a conjectural example (clearly marked as conjecture). > Such should prove enlightening not only to earlier posters, but > to me as well. A day spent without learning SOMETHING is a poor > day indeed. > > It seems odd that X3J11 or its members would come up with such claims > about main(). It would seem to fly in the face of years of established > practice of using exit(condition) as a way to terminate programs. > Declaring such programs non-portable does not seem to me to be a > productive use of X3J11's time; obviously, I can use a little bit of > education from someone who knows better than myself. Here's a *hypothetical* implementation which goes wrong. Suppose the stack is used for returning function values, like this: * called function: on entry, allocate enough stack space for the function value on return, copy the function value into the stack space previously allocated * calling function: when the called function returns, pop the function value off the stack Clearly, the called and calling functions must agree about the type of the called function, or else the stack pointer gets mispositioned. This would not normally be an issue here if main() calls exit() instead of returning normally. However, in this hypothetical implementation, one of the things that exit() does is to deliberately unwind the stack to the point before when main() was called. [Why? Well, maybe it wants to make as much stack as possible available for whatever it's going to do next, like i/o rundown or calling an exit handler.] This unwinding process might lead to a mispositioned stack-pointer just as an ordinary return might. I don't know of any real implementation that does things exactly like this, but I don't think that this hypothetical implementation is so outrageous that it should be ruled out of order. Your code is non-portable. In general, if two parts of your program (and supporting code) disagree on the type of a function, you are just begging for trouble. If all you wish to do is to avoid a warning message from a finicky compiler, why don't you just PRETEND that main() is returning something? Brendan McKay. bdm@anucsd.oz or bdm@anucsd.oz.au or bdm659@csc1.anu.oz.au