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
