Timeline for Why should main() be short?
Current License: CC BY-SA 3.0
20 events
when toggle format | what | by | license | comment | |
---|---|---|---|---|---|
Jun 22, 2011 at 20:52 | comment | added | Martin Vilcans | That's interesting, @Rob. I didn't know that you are not allowed to call main. Not that it matters because I would never want to in the first place. | |
Jun 21, 2011 at 21:54 | comment | added | William |
This reminds me of jQuery's return new jQuery.init(a,b) trick. Basically it provides additional functionality by allowing you to override the function later.
|
|
Jun 21, 2011 at 21:48 | comment | added | Rob Kennedy |
Yes, @Martin, if you called main recursively, then your C++ program was ill-formed, so it wasn't a valid test. As far as I can tell, implementations may indeed simply call exit(main()) — since programs aren't allowed to call main themselves (like your test did), the implementation doesn't really need to worry about inserting special code in the function epilogue just to guarantee that returning from it acts like exit .
|
|
Jun 21, 2011 at 21:40 | comment | added | Martin Vilcans |
@Rob Kennedy Well, I tested it with g++ too and got the same result, but perhaps it doesn't follow the standard. When I read that a return from main should call exit, I assumed that the typical implementation is a library function that calls main, and then exit, i.e. exit(main()) . What you're saying makes less sense, but may be right.
|
|
Jun 21, 2011 at 21:07 | comment | added | Rob Kennedy |
C is a little different from C++ in that regard, @Martin. C allows recursive calls to main , so it says that returning from the initial call to main is the same as calling exit . In the scenario we're imagining here, there are two main functions: the host application's, and the one you import from a library. Calling the imported function would be the initial call of that function, so returning from it should terminate your program. (I doubt how many implementations actually work that way, though, since they probably don't expect to export main anyway.)
|
|
Jun 21, 2011 at 20:47 | comment | added | Martin Vilcans | I tested on gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3. I can call the main from other functions without there being an implicit exit call. | |
Jun 21, 2011 at 15:53 | comment | added | Rob Kennedy |
@Coder, if returning from main does not have the effect of calling exit on your compiler, then your compiler doesn't follow the standard. That the standard dictates such behavior for main proves that there is something special about it. The special thing about main is that returning from it has the effect of calling exit . (How it does that is up to compiler writers. The compiler could simply insert code in the function epilogue that destroys static objects, calls atexit routines, flushes files, and terminates the program — which, again, isn't something you want in a library.)
|
|
Jun 21, 2011 at 15:37 | comment | added | Coder |
@Rob, I would like to see how *nix behaves, but in Windows, main is a very ordinary function, and if you'll export it, I am quite sure it will not exit the application, because exit is called by the wrapping function. Unless you kill the application and process with exit(0) , but you can do that from every function, so nothing special about main here. Also it's a good question if exported main is THE main . Also, not that quote says leaving main , so main is gone, and then, who calls exit is not even specified.
|
|
Jun 21, 2011 at 15:22 | comment | added | Rob Kennedy |
@Coder, whether exit leaves main is irrelevant. We're not discussing the behavior of exit . We're discussing the behavior of main . And the behavior of main includes the behavior of exit , whatever that may be. That's what makes it undesirable to import and call main (if doing such a thing is even possible or allowed).
|
|
Jun 21, 2011 at 15:18 | comment | added | Rob Kennedy | Now you're doing it wrong, @Coder. Your object has automatic storage duration. The standard says objects with static storage duration are destroyed, so it wasn't a valid test. Your conclusion does not follow from your test. Besides, all you can hope to learn from your test is whether your compiler follows the standard. | |
Jun 21, 2011 at 15:16 | comment | added | Coder | @Rob, C++03 §3.6.1/5: "A return statement in main has the effect of leaving the main function … and calling exit with the return value as the argument." This is true, but exit doesn't leave the main, it terminates process, there is no scope cleanup! Also stack cookie checking will not take place. Main is just a regular function which is wrapped inside the true entry point! See: catch22.net/tuts/minexe C-runtime and default libs. | |
Jun 21, 2011 at 15:06 | comment | added | Coder | @Rob, Just verified. New class (classx) with ctor and dtor. Main with body - case1: {classx a;return 0;} and case2: {classx a;exit(0);}. Dtor in case1 is called, dtor in case 2 is NOT called. If you have object deserialization in dtor, it's not doing anything if you call exit! Yes memory is cleaned, but exit kills the process right there, no dtors executed. Tested with VS2010, win32, debug. | |
Jun 21, 2011 at 13:58 | comment | added | Rob Kennedy |
@Coder, see C++03 §3.6.1/5: "A return statement in main has the effect of leaving the main function … and calling exit with the return value as the argument." Also see §18.3/8, which explains that "objects with static storage duration are destroyed" and "all open C streams … are flushed" when you call exit . C99 has similar language.
|
|
Jun 21, 2011 at 9:44 | comment | added | tdammers | @shoosh: main() is a special function, most compilers automatically make it the entry point for an application. If you want to make main() a library function, programs using the library will be forced to use the library's main() instead of their own, which is generally undesirable. Also, you cannot combine two libraries when both of them define main(). In short, defining main() in a library is evil. | |
Jun 21, 2011 at 8:40 | comment | added | Coder | @Rob, no it does not. If it calls exit, you are doing it WRONG. Exit doesn't do any cleanups, it just kills the CRT and process right there. No destructors in main scope are called. The real entry point MainCRTStartup or something initializes heap, does bunch of stuff, then calls main, and upon return calls exit or some-such. | |
Jun 20, 2011 at 22:00 | history | migrated | from stackoverflow.com (revisions) | ||
Jun 20, 2011 at 21:53 | comment | added | Rob Kennedy |
I suppose it might be more accurate to say you can't import it, @Shoosh. The C++ standard forbids calling it from your own code. Besides, its linkage is implementation-defined. Also, returning from main effectively calls exit , which you usually don't want a library to do.
|
|
Jun 20, 2011 at 21:52 | vote | accept | CommunityBot | ||
Jun 20, 2011 at 21:45 | comment | added | shoosh |
> You cannot export main -- why?
|
|
Jun 20, 2011 at 21:35 | history | answered | Rob Kennedy | CC BY-SA 3.0 |