On Thu, Dec 29, 2011 at 7:16 PM, Jonathan M Davis <jmdavisp...@gmx.com> wrote: > > A D exit function would have to do essentially the same thing as throw an > exception and catch it in main anyway. The only way that the stack is going to > be unwound properly is if you actually unwind it. The only way in the language > to do that without actually returning from each and every function on the > stack is to throw an exception. > > How many modern languages do you know of with an exit function that cleans > everything up properly? C++ won't for the same reasons that D won't. Java gets > away with it because it doesn't have destructors or scope statements or > anything else that would actually require unwinding the stack. > > All a D exit function _could_ do would be to throw an exception and then have > the runtime catch it - which still wouldn't work if the programmer was foolish > enough to do something like > > catch(Exception) {} > > in their code. So, throwing an exception and catching it _is_ the way to do > it, and it really makes more sense if you're doing it yourself, since then > you're less likely to make that mistake and catch all Exceptions somewhere in > your code and eat the one which is supposed to exit the program. > > - Jonathan M Davis
Hm...embarassingly, it didn't occur to me that C++ didn't clean up either; but sure enough, the following code shows that exit() breaks C++ RAII. #include <iostream> #include <cstdlib> struct SafeExit { ~SafeExit() { std::cout << "Safely exit with destructor." << std::endl; } }; int main(int argc, char** argv) { SafeExit safeExit; std::cout << "Test if std.c.stdlib.exit() breaks RAII." << std::endl; std::cout << "Pre-exit!" << std::endl; exit(0); std::cout << "Post-exit! Should not get here!" << std::endl; return 0; } On the other hand, ruby happily *does* unwind the stack properly on exit(). def safe_exit begin yield ensure puts "Safely exit with ensure." end end safe_exit do puts "Test if std.c.stdlib.exit() breaks RAII." puts "Pre-exit!" exit(0); puts "Post-exit! Should not get here!" end Honestly, I would rather have the latter robustness. While I have always thought of abort() as being a dirty exit, I had, until now, always thought of exit() as being very safe. Violating RAII on a safely-intended exit() is a really Bad Thing, I would think. Since D could conceivably implement a very safe exit() without an explicit use of Exceptions to get around the "catch Exception() {}" problem you mentioned above, does it make sense to request a safer exit() feature for D? Ashish