Exception/Error division in D
Steven Schveighoffer
schveiguy at yahoo.com
Thu May 24 11:39:34 PDT 2012
On Thu, 24 May 2012 06:27:12 -0400, Denis Shelomovskij
<verylonglogin.reg at gmail.com> wrote:
> Let's talk about an abstract situation without caring about breaking
> existing code, current docs, implementation etc.
>
> Definitions:
> * an Exception is something that tigers scope guards and executes
> catch/finally blocks if thrown;
> * an Error is something that doesn't do it.
I'll give you a different definition:
* an Exception is something that can be handled far away from the context
of the error, because the system can safely unwind the stack.
* an Error must be handled at the point the error occurred, or the program
state is by definition invalid.
>
> As a result _we can't do any clean-up if an Error is thrown_ because
> scope guards and catch/finally blocks aren't executed and the program is
> in invalid state because of this. Of course it's theoretically possible
> to code without scope guards and catch/finally blocks but isn't
> applicably for a real project. E.g. in some editor if and Error is
> thrown there is no ability to save opened documents.
>
>
> Main Question: What do you think can be an Error?
>
> Can "Integer Divide by Zero" be an Error? Definitely, not.
I agree with you there. However, the problem isn't nearly as bad as you
say. The runtime doesn't actually deal with SIGFPE on Unix based systems,
and most places where an "Error" is thrown, it's within asserts, which are
compiled out in release code.
If you get one of these, you can handle the signal. I think on Windows
it's handled for you, but there should be a way to intercept this and do
recovery.
> Can "Access Violation" be an Error? No, because it's very common to
> access a field/virtual member function of a null object.
I'd argue this is unrecoverable. Access Violation results from
corruption, and the damage has already been done. Even a null pointer
access can be the cause of previous corruption. There is no "recovery"
from memory corruption. There is no way to plan for it.
Now, if you want to handle it specifically for your program, that should
be doable, at your own risk. But there's no way throwing an Exception is
a valid result.
> Can "Out of memory" be an Error? No, because e.g. if I read a user file
> that require me to create a large array (> 100 MiB, e.g.) I don't want
> to crash, but just tell, that "Dear user, the file can't be opened
> because it requires..."
Right, out of memory is only an error if your program's invariant depends
on the memory allocation. You can plan for the above easily enough, but
not realistically for all tasks and all library code that require
allocation.
For example, let's say you are restructuring a hash table, and you
reallocate some nodes. You have half transferred over the old structure
to the new structure, and you run out of memory. How to recover from this?
In summary, I think we can adjust Windows divide by zero errors to allow
you to handle them manually, the Posix version is fine (no Error is
generated), access violations are unequivocally Errors, and out of memory
should be fixable by making allocation routines that do not throw (just
return null).
An interesting idea would be to allow a global "handler" for all errors.
So if you throw an Exception, it unwinds the stack like normal. If you
throw an Error, it checks a handler to see if you want to handle that
error (via registering a function/delegate), and if not handled throws
Error without properly unwinding the stack.
-Steve
More information about the Digitalmars-d
mailing list