www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Regarding nothrow and safe

reply Sean Eskapp <eatingstaples gmail.com> writes:
Does nothrow mean the function itself does not through exceptions, or that the
function body, as well as any called functions, do not throw? I wonder because
allocating new memory inside a  safe nothrow function works, even though I'm
used to "new" allocations throwing exceptions or Out-Of-Memory errors.
Aug 20 2011
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Sean Eskapp:

 Does nothrow mean the function itself does not through exceptions, or that the
 function body, as well as any called functions, do not throw? I wonder because
 allocating new memory inside a  safe nothrow function works, even though I'm
 used to "new" allocations throwing exceptions or Out-Of-Memory errors.
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. Bye, bearophile
Aug 20 2011
parent reply Sean Eskapp <eatingstaples gmail.com> writes:
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.
Aug 20 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2011 08:18 PM, 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.
You can catch errors, if you want to deal with them.
Aug 20 2011
parent reply Sean Eskapp <eatingstaples gmail.com> writes:
== Quote from Timon Gehr (timon.gehr gmx.ch)'s article
 On 08/20/2011 08:18 PM, 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.
You can catch errors, if you want to deal with them.
Oops, right. In my mind, exceptions are still anything which can be thrown or caught. I need to remember that it has a more specific meaning in D.
Aug 20 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/20/2011 08:25 PM, Sean Eskapp wrote:
 == Quote from Timon Gehr (timon.gehr gmx.ch)'s article
 On 08/20/2011 08:18 PM, 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.
You can catch errors, if you want to deal with them.
Oops, right. In my mind, exceptions are still anything which can be thrown or caught. I need to remember that it has a more specific meaning in D.
But note that you cannot explicitly throw an error from a nothrow function. nothrow functions can throw memory exceeded errors or assertion failure errors. I don't think they can throw other things.
Aug 20 2011
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Aug 20 2011
parent reply Jacob Carlborg <doob me.com> writes:
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. -- /Jacob Carlborg
Aug 21 2011
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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
Aug 21 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Jacob Carlborg" <doob me.com> wrote in message 
news:j2qn7n$1db7$1 digitalmars.com...
 On 2011-08-21 02:26, Jonathan M Davis wrote:
 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.
I remember some discussion awhile back about having some sort of scheme in the GC where you could tell the GC "Hey, in low-memory situations, instead of bailing out with an Error, call this delegate I'm giving you and I'll try to clear out my caches to free up some memory." Unfortunately, I don't think anything's actually come out of that so far. I really hope it does though, it's a great idea.
Aug 25 2011
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Thursday, August 25, 2011 11:38 Nick Sabalausky wrote:
 "Jacob Carlborg" <doob me.com> wrote in message
 news:j2qn7n$1db7$1 digitalmars.com...
 
 On 2011-08-21 02:26, Jonathan M Davis wrote:
 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.
I remember some discussion awhile back about having some sort of scheme in the GC where you could tell the GC "Hey, in low-memory situations, instead of bailing out with an Error, call this delegate I'm giving you and I'll try to clear out my caches to free up some memory." Unfortunately, I don't think anything's actually come out of that so far. I really hope it does though, it's a great idea.
Not a bad idea. It would still have to throw an OutOfMemoryError if it really couldn't free enough memory, but it would still improve the situation for anyone looking to use caches or anything else which could have its memory freed and still allow the program to function correctly if the memory consumption gets too high. - Jonathan M Davis
Aug 25 2011
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, August 20, 2011 16:41:01 Sean Eskapp wrote:
 Does nothrow mean the function itself does not through exceptions, or that
 the function body, as well as any called functions, do not throw? I wonder
 because allocating new memory inside a  safe nothrow function works, even
 though I'm used to "new" allocations throwing exceptions or Out-Of-Memory
 errors.
A nothrow function must not allow any Exceptions escape from it. So, it must either catch them all or it must only call functions which are nothrow and throw nothing itself. An Error can still escape a nothrow function (though you may not be able to throw one manually, I don't know), because when an Error occurs, your program is pretty much toast. You're not normally supposed to try and catch those. - Jonathan M Davis
Aug 20 2011