On May 24, 2012, at 11:39 AM, Steven Schveighoffer wrote:

> On Thu, 24 May 2012 06:27:12 -0400, Denis Shelomovskij 
> <[email protected]> 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.

This is a good point.  OutOfMemory conditions aside, the only time I'd want to 
recover from an Error condition was at the point the event occurred, not 
somewhere up the stack.


>> 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.

Right.  Recovery is potentially valid at the point of failure, not somewhere up 
the stack.


>> 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?

I think it's fair to expect code that allocates be exception-safe in the face 
of allocation errors.  I know I'm always very careful with containers so that 
an allocation failure doesn't result in corruption, for example.


> 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).

It would be kind of cool if there were some sort of unified way to handle 
system-generated errors, though I don't know that this is practical.  signals 
sort of work on Windows, but I'm pretty sure the contextual sigaction stuff 
does not.


> 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.

^^ this

Reply via email to