Regarding nothrow and @safe
Jonathan M Davis
jmdavisProg at gmx.com
Sun Aug 21 13:04:47 PDT 2011
On Sunday, August 21, 2011 12:38:47 Jacob Carlborg wrote:
> On 2011-08-21 02:26, Jonathan M Davis wrote:
> > On Saturday, August 20, 2011 18:18:25 Sean Eskapp wrote:
> >> bearophile:
> >>> As far as I know they have decided to make memory overflow errors,
> >>> so
> >>> they are
> >>
> >> not exceptions, you can't catch them. Other people will confirm this
> >> or not.
> >>
> >> In this case, how would you go about handling out-of-memory
> >> situations? A systems programming language should certainly give the
> >> programmer the option to deal with this.
> >
> > The short answer: You don't. It's an incredibly bad idea.
> >
> > The long answer: You catch Error - or OutOfMemoryError if you want that
> > specific one. So, you could try and catch it and handle it, but most of
> > the cleanup during the unwinding of the stack gets skipped. scope
> > statements and destructors don't get called. Your program is not likely
> > to be in state where it makes any real sense to try and continue. You
> > _can_ do it, but it's a bad idea.
> >
> > - Jonathan M Davis
>
> What about if you have an application doing heavy image/video
> processing, the application could empty some caches or similar. The
> application could still work, just not as fast as with caches.
Things do _not_ get cleaned up properly when an Error is thrown. Destructors,
finally blocks, and scope statements are skipped when any type of exception
which is not derived from Exception (directly or indirectly) is thrown. Errors
are considered unrecoverable.
Now, you _can_ catch Errors. You _can_ try and continue to execute your
program. But, there are no guarantees that your program is still in a sane
state, because anything which could have been affected by destructors, finally
blocks, and scope statements being skipped could be in a state which your
program does not expect and cannot handle.
Read page 307 of TDPL. It talks about "nothrow Functionsa and the Special
Nature of Throwable." What it says applies to all throwables which are not
derived from Exception. That's why when you have a nothrow function, like this
void func() nothrow
{
try
throwFunc();
catch(Exception e)
assert(0, "It threw!");
}
void throwFunc()
{
throw new Exeception("Exception!");
}
catching Exception is enough. Anything not derived from Exception is not
considered in nothrow and is considered unrecoverable. So, attempt to recover
from an OutOfMemoryError at your own peril.
In the case of your image/video application, it might be able to recover and
continue if you were able to catch the OutOfMemoryError at its source before
it started propagating up the calcl stack, but as soon as it starts skipping
stuff that a normal Exception wouldn't have skipped, your program is effectively
in an invalid state. If you really wanted to do what you describe, you'd
probably want to use custom memory allocators, which is on the todo list, I
believe (and is one of the major reasons why Andrei isn't farther on
std.container yet; he wants to sort out his custom memory allocator scheme
first). But trying to catch and recover from an Error is generally a _very_ bad
idea.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list