walterm@hpwrce.HP.COM (Walter Murray) (06/27/91)
Is the following program strictly conforming? int main(void) { return; } Many people have written that the main function must return a value. I can't find such a requirement in the Standard. I have read 2.1.2.2.3 and 3.6.6.4. Am I missing something? Walter Murray
michi@ptcburp.ptcbu.oz.au (Michael Henning) (06/28/91)
walterm@hpwrce.HP.COM (Walter Murray) writes: >Is the following program strictly conforming? > int main(void) { return; } >Many people have written that the main function must return a value. >I can't find such a requirement in the Standard. I have read 2.1.2.2.3 >and 3.6.6.4. Am I missing something? Section 2.1.2.2.3 (Program termination) is quite explicit: "A return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument. If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined." Section 3.6.6.4 (The return Statement) says: "If a return statement without an expression is executed, and the value of the function call is used by the caller, the behavior is undefined." Note that for section 3.6.6.4 to apply, there must be a caller, but the caller in this case is the environment, so 2.1.2.2.3 applies instead. The upshot is that the program is strictly conforming, but the exit status the OS gets to see is undefined. To write truly portable code, it pays to explicitely call exit() since some (non-conforming) implementations to not return a defined value to the OS when a return from main is executed (even if that return specifies a value). So it pays to write int main(void) { exit(0); } to be sure. Unfortunately, many versions of lint will complain about an undefined return value from main in this case, because they do not know about exit(). If you want to be paranoid, you can write int main(void) { exit(0); return 0; /* Keep lint happy */ } Michi. -- -m------- Michael Henning +61 75 950255 ---mmm----- Pyramid Technology +61 75 522475 FAX -----mmmmm--- Research Park, Bond University michi@ptcburp.ptcbu.oz.au -------mmmmmmm- Gold Coast, Q 4229, AUSTRALIA uunet!munnari!ptcburp.oz!michi
diamond@jit533.swstokyo.dec.com (Norman Diamond) (06/28/91)
In article <7830001@hpwrce.HP.COM> walterm@hpwrce.HP.COM (Walter Murray) writes: >Is the following program strictly conforming? > int main(void) { return; } >Many people have written that the main function must return a value. >I can't find such a requirement in the Standard. I have read 2.1.2.2.3 >and 3.6.6.4. Am I missing something? For the effect of the program to be defined, the main function must return a value. It does seem strange that the compiler is required to issue a diagnostic for a return statement with a value in a void function, but not for the opposite mistake. OK, if you don't want your program to send a small nuclear device at your car, the main function must return a value. (2.1.2.2 neither allows nor disallows this extreme an effect; 3.6.6.4 allows it.) -- Norman Diamond diamond@tkov50.enet.dec.com If this were the company's opinion, I wouldn't be allowed to post it. Permission is granted to feel this signature, but not to look at it.
hooverm@sysjj.mdcbbs.com (SQUID 6 on the DARK side) (06/28/91)
In article <1991Jun28.043342.27540@ptcburp.ptcbu.oz.au>, michi@ptcburp.ptcbu.oz.au (Michael Henning) writes: > walterm@hpwrce.HP.COM (Walter Murray) writes: > >>Is the following program strictly conforming? > >> int main(void) { return; } > >>Many people have written that the main function must return a value. >>I can't find such a requirement in the Standard. I have read 2.1.2.2.3 >>and 3.6.6.4. Am I missing something? > >...stuff deleted... > > some (non-conforming) implementations to not return a defined value > to the OS when a return from main is executed (even if that return > specifies a value). So it pays to write > > int main(void) { exit(0); } > > to be sure. Unfortunately, many versions of lint will complain about > an undefined return value from main in this case, because they do not > know about exit(). If you want to be paranoid, you can write > > int main(void) > { > exit(0); > return 0; /* Keep lint happy */ > } I've run into this problem running code on 3 platforms (VMS,SUN & PC) I use: void main() { insert magic code here } This seems to work well on all three platforms. Mark <o===6
kremer@cs.odu.edu (Lloyd Kremer) (06/28/91)
In article <1991Jun28.043342.27540@ptcburp.ptcbu.oz.au> michi@ptcburp.ptcbu.oz.au (Michael Henning) writes: >If you want to be paranoid, you can write > >int main(void) >{ > exit(0); > return 0; /* Keep lint happy */ >} int main(void) { exit(0); /*NOTREACHED*/ /* Keeps most lints happy without extra code */ } Lloyd Kremer Hilton Systems, Inc. kremer@cs.odu.edu
exspes@gdr.bath.ac.uk (P E Smee) (06/28/91)
In article <7830001@hpwrce.HP.COM> walterm@hpwrce.HP.COM (Walter Murray) writes: >Is the following program strictly conforming? > > int main(void) { return; } > >Many people have written that the main function must return a value. >I can't find such a requirement in the Standard. I have read 2.1.2.2.3 >and 3.6.6.4. Am I missing something? Yep. The construct you used, 'int main (...' declares main to be a function which returns an int. You have declared it as returning a value, and then not returned a value of the type specified. Speaking pedantically, that's a prima facie violation. In practice, since return from main() generally throws you out of your C-program environment, and back into your native operating system environment, whether or not it makes any difference depends on your OS. Many OSes expect progs to return status codes -- especially progs which have been declared to return status codes. If you don't return one, the results will be OS-dependent but can range the full gamut from unpleasantly surprising to unpleasantly mysterious. If you're really unlucky, your failure to return the value you promised won't make any difference at all -- until next year, when you've got to move the prog to another OS platform and have forgotten what you did. -- Paul Smee, Computing Service, University of Bristol, Bristol BS8 1UD, UK P.Smee@bristol.ac.uk - ..!uunet!ukc!bsmail!p.smee - Tel +44 272 303132
steve@taumet.com (Stephen Clamage) (06/28/91)
michi@ptcburp.ptcbu.oz.au (Michael Henning) writes: >The upshot is that the program is strictly conforming, but the exit >status the OS gets to see is undefined. No. A strictly-conforming program "shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior" (section 1.7). >So it pays to write >int main(void) { exit(0); } Except that EXIT_SUCCESS need not have the value 0. This might be wrong in an ANSI environment. -- Steve Clamage, TauMetric Corp, steve@taumet.com
eggert@twinsun.com (Paul Eggert) (06/29/91)
steve@taumet.com (Stephen Clamage) writes: >michi@ptcburp.ptcbu.oz.au (Michael Henning) writes: >>So it pays to write >>int main(void) { exit(0); } >Except that EXIT_SUCCESS need not have the value 0. This might be >wrong in an ANSI environment. But section 4.10.4.3 says that exit(0) and exit(EXIT_SUCCESS) have the same effect even if EXIT_SUCCESS!=0. Anyway, Posix 1003.1-1990 (section 8.1) says that EXIT_SUCCESS==0, so hosts where EXIT_SUCCESS!=0 are an endangered species.
gwyn@smoke.brl.mil (Doug Gwyn) (06/29/91)
In article <7830001@hpwrce.HP.COM> walterm@hpwrce.HP.COM (Walter Murray) writes: >Many people have written that the main function must return a value. >I can't find such a requirement in the Standard. I have read 2.1.2.2.3 >and 3.6.6.4. Am I missing something? You must be -- 2.1.2.2.3 states explicitly "If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined." That meets the condition for causing undefined behavior on at least two counts.
gwyn@smoke.brl.mil (Doug Gwyn) (06/29/91)
In article <787@taumet.com> steve@taumet.com (Stephen Clamage) writes: >Except that EXIT_SUCCESS need not have the value 0. This might be >wrong in an ANSI environment. No -- while it is true that EXIT_SUCCESS might be defined as a nonzero value, a conforming hosted implementation must also support the exit status value 0 as a "separate but equal" way to specify successful termination status.
gwyn@smoke.brl.mil (Doug Gwyn) (06/29/91)
In article <1991Jun28.055840.29919@tkou02.enet.dec.com> diamond@jit533.enet@tkou02.enet.dec.com (Norman Diamond) writes: >It does seem strange that the compiler is required to issue a diagnostic for >a return statement with a value in a void function, but not for the opposite >mistake. That's because a vast amount of existing, correct (as of when it was written) C code is like that. Before there was a "void" type in C, the effect of a void-valued function was achieved by coding a (default) int-valued function and not returning a value. It's easy for an implementation to deal with this common practice (either by not worrying about loading the result register or by building a dummy result value before the function exit code), and as a widespread officially-sanctioned practice (K&R 1st Ed. had examples), there was no good reason to disallow this usage. All that X3J11 had to do along these lines was to note the obvious fact that an attempt to use a value that the program hadn't bothered to set up would be nonsensical.
gwyn@smoke.brl.mil (Doug Gwyn) (06/29/91)
In article <1991Jun28.072521.1@sysjj.mdcbbs.com> hooverm@sysjj.mdcbbs.com (SQUID 6 on the DARK side) writes: >I use: > void main() > { > insert magic code here > } >This seems to work well on all three platforms. Damn it, this is comp.std.c, not comp.lang.c.neophyte. Walter Murray was asking a standard-related question; he presumably doesn't care any more than I do whether or not you have successfully gotten away with violations of the C standard using a small number of specific implementations.
lmiller@aero.org (Lawrence H. Miller) (06/29/91)
In article <16575@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <7830001@hpwrce.HP.COM> walterm@hpwrce.HP.COM (Walter Murray) writes: >>Many people have written that the main function must return a value. >>I can't find such a requirement in the Standard. I have read 2.1.2.2.3 >>and 3.6.6.4. Am I missing something? > >You must be -- 2.1.2.2.3 states explicitly "If the main function executes a >return that specifies no value, the termination status returned to the host >environment is undefined." That meets the condition for causing undefined >behavior on at least two counts. The question one might ask of a standards body is why this is "undefined" and not "implementation defined," since it clearly involves the program's interaction with its host. This is, in fact, alluded to in the description of the exit() function in 4.10.4.3: If the value [returned] is EXIT_SUCCESS... If the value [returned] is EXIT_FAILURE... Otherwise the status returned is implementation-defined. -- Larry Miller The Aerospace Corporation lmiller@aero.org (213 soon to be 310)336-5597
steve@groucho.ucar.edu (Steve Emmerson) (06/29/91)
In <16577@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <787@taumet.com> steve@taumet.com (Stephen Clamage) writes: >>Except that EXIT_SUCCESS need not have the value 0. This might be >>wrong in an ANSI environment. >No -- while it is true that EXIT_SUCCESS might be defined as a nonzero value, >a conforming hosted implementation must also support the exit status value 0 >as a "separate but equal" way to specify successful termination status. In a POSIX environment, at least, EXIT_SUCCESS *is* 0. Period. Are there non-POSIX (or pre-POSIX) environments in which EXIT_SUCCESS is (or was) not zero (I know about VMS)? Steve Emmerson steve@unidata.ucar.edu ...!ncar!unidata!steve
gwyn@smoke.brl.mil (Doug Gwyn) (06/29/91)
In article <1991Jun29.002410.27632@aero.org> lmiller@aero.org (Lawrence H. Miller) writes: >The question one might ask of a standards body is why this is "undefined" >and not "implementation defined," since it clearly involves the program's >interaction with its host. I don't think you understand what these terms mean as used in the C standard. Either that, or you really believe that an implementation could document what would happen for every program that returned garbage instead of a deliberate value, where the garbage is NOT specified in the program (unlike the case for the part of 4.10.4.3 that you quoted). Basically, this was specified to cause undefined behavior because that's exactly what it does.
lmiller@aero.org (Lawrence H. Miller) (06/30/91)
In article <16582@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <1991Jun29.002410.27632@aero.org> lmiller@aero.org (Lawrence H. Miller) writes: >>The question one might ask of a standards body is why this is "undefined" >>and not "implementation defined," since it clearly involves the program's >>interaction with its host. > >I don't think you understand what these terms mean as used in the C >standard. Either that, or you really believe that an implementation >could document what would happen for every program that returned >garbage instead of a deliberate value, where the garbage is NOT >specified in the program (unlike the case for the part of 4.10.4.3 >that you quoted). > >Basically, this was specified to cause undefined behavior because >that's exactly what it does. I understand fully well what the terms "undefined" and "implementation defined" mean. I don't understand what the term "garbage" means and can't find it defined anywhere in the standard. -- Larry Miller The Aerospace Corporation lmiller@aero.org (213 soon to be 310)336-5597
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/30/91)
In article <16582@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: > Either that, or you really believe that an implementation > could document what would happen for every program that returned > garbage instead of a deliberate value, where the garbage is NOT > specified in the program (unlike the case for the part of 4.10.4.3 > that you quoted). I really believe that an implementation could document what would happen for every program that returned garbage instead of a deliberate value. At most it would take a special case in the compiler: ``Oh, a void return inside main? Let's make that return 0.'' Then the documentation would reflect this. > Basically, this was specified to cause undefined behavior because > that's exactly what it does. That's what it does in historical implementations, but ANSI tightened up on a lot of minor points, and they could easily have taken care of this one. I'm not saying this is necessarily a good idea, but you can't just throw out the question. Why would it have been bad to insist on implementation-defined behavior? *Why* is undefined a better idea? ``That's exactly what it does'' is not an excuse; if you took that logic, it would be undefined whether static variables are initialized to 0, undefined whether unions of structs beginning with the same type in fact overlapped, and undefined whether int a[n]; a + n is always valid. ---Dan
gwyn@smoke.brl.mil (Doug Gwyn) (06/30/91)
In article <12049.Jun2922.08.1391@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >> Basically, this was specified to cause undefined behavior because >> that's exactly what it does. >That's what it does in historical implementations, but ... Ok, this really isn't worthy of protracted discussion, but what I mean is that the natural, simplest implementation of function return would not (as well as historically did not) invent well-defined values for programs that do not at all specify the values. In the case of default initialization of statics, while it may appear that the programmer has left the contents unspecified, he really hasn't, because K&R guaranteed that they would contain 0. There was never any guarantee that return from an int-valued function would create some well-defined value (say, 0), but K&R did make it clear that so long as one didn't intend to use a value there was no need to return one. (This may have been different if void-valued functions had existed from the beginning.) As the only acknowledged public specification of the C language, K&R had to be taken as the main guide for settling questions about the existing rules. Given that anonymous return in general produces an unspecified value, anonymous return from main() naturally would do the same. To make it different from other functions would require a special-case wart, and the one the standard already requires (accepting "int main(void)") was already rather controversial. ("int main(void)" would probably not have been blessed were it not for the fact that K&R indicated clearly that programmers could expect it to work, so there was a huge amount of existing, arguably correct, code that relied on that behavior.) While you can argue that you would like to add some more default rules such as automatic 0 values for anonymous returns, that qualifies as new invention and thus joins literally hundreds of similar suggestions in the "not appropriate for standardization" category.
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (06/30/91)
In article <16587@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: > Given that anonymous return in general produces an unspecified value, > anonymous return from main() naturally would do the same. Hold on. You're saying something about the real world here, and the real world doesn't distinguish between ``implementation-defined'' and ``undefined'' until a standard comes along and forces the issue. ANSI could easily have left these decisions up to the implementation, and you haven't given any excuse for the undefined behavior that wouldn't apply equally well to implementation-defined behavior. Or are you claiming that ANSI never forced implementations to define behaviors where the behavior in general produced unspecified effects? I think not. If that were so, ``implementation-defined'' wouldn't even be in the standard. Everything would be ``undefined.'' > While you can argue that you would like to add some more default rules > such as automatic 0 values for anonymous returns, Yikes, why would I argue for something like that? I was just giving an example of what an implementation could do to define the value. Nobody in his right mind would standardize such a rule when it breaks so many existing implementations for no good reason. ---Dan
gwyn@smoke.brl.mil (Doug Gwyn) (06/30/91)
In article <16020.Jun3004.44.3491@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >Hold on. You're saying something about the real world here, and the real >world doesn't distinguish between ``implementation-defined'' and >``undefined'' until a standard comes along and forces the issue. Sure it does. If it core dumps, it's undefined, and if it's documented in the long shelf of vendor literature, it's implementation-defined.