Bug or feature? std.c.stdlib.exit() breaks RAII
Ashish Myles
marcianx at gmail.com
Thu Dec 29 20:03:23 PST 2011
On Thu, Dec 29, 2011 at 7:16 PM, Jonathan M Davis <jmdavisProg at 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
More information about the Digitalmars-d-learn
mailing list