On Wednesday, June 13, 2018 10:56:41 wjoe via Digitalmars-d-learn wrote: > On Wednesday, 13 June 2018 at 03:14:33 UTC, Jonathan M Davis > > wrote: > > Most programs do not handle the case where they run out of > > memory and cannot continue at that point. For better or worse, > > D's GC was designed with that in mind, and it treats failed > > allocations as an Error. In the vast majority of cases, this is > > desirable behavior. In those cases when it isn't, alternate > > memory allocation schemes such as malloc can be used. But > > But manual memory management sucks and is a huge waste of > everyone's time and I was hoping to get the best from both worlds > > :) > :
Well, I think that the reality of the matter is that the number of programs that even attempt to recover from not having enough memory is extremely small such that you're dealing with a very niche case if you're going to try it, and if the GC fails to allocate more memory for you, your options are typically pretty limited. So, even if the GC provided a way to allocate memory that returned null on failure instead of throwing an Error, I don't know that it would do you a lot of good, but regardless, the GC was not designed with that in mind, and even GC.malloc throws OutOfMemoryError on allocation failure rather than null. So, there isn't much choice on the matter. > > regardless of whether the decision to treat failed memory > > allocations as an Error was a good one or not, the fact remains > > that as soon as an Error is thrown, you lose the ability to > > deal with things cleanly, because full clean up is not done > > when an Error is thrown (and can't be due to things like how > > nothrow works). So, regardless of whether a failed memory > > allocation is a condition that can be recovered from in > > principle, the way that D handles GC allocations make it > > unrecoverable in practice - at least as far as GC-allocated > > memory is concerned. > > Did I get that right? > You say when an error is thrown destructors, scope statements, > etc. are not executed - if declared as nothrow because the > exception handler mechanism stuff is missing, is that correct? > And it does execute if not declared as nothrow but can't be > relied upon because some other nothrow functions could have > omitted some of those statements? Yes, and there's no guarantee that clean-up will occur even if nothing is nothrow. While the current implementation will do clean-up in those cases, it didn't used to, and Walter has repeatedly stated that it is not guaranteed to do so. Errors are _not_ intended to be caught and recovered from. They're essentially a segfault that prints a message and stack trace but which for some reason uses the exception throwing mechanism to get to the code that prints the message and exits the program. > So I shoot myself in the foot with nothrow and if I don't use it > I'm still in a world of hurt? > > I understand the idea that an Error is not supposed to be caught > but why would such a 'feature' be desirable? Where's the benefit > if nothing can be relied upon ? > > If all errors would be treated like an exception, the developer > could decide whether it is an error which needs to terminate > right away or be able to handle the issue and continue or > gracefully shutdown. The idea is that because your program is in an invalid state, attempting a graceful shutdown is unsafe. But regardless of whether you agree with that, the fact that nothrow doesn't do clean-up pretty much ensures that it isn't safe in the general case, and nothrow can't do clean-up without negating one of the main reasons that it exists in the first place - which is to improve performance by not emitting exception-handling code. > Could even set a break point or force a core > dump right there. The fact that Errors don't immediately kill the program and instead sort of unwind the stack is a definite problem for getting good debug information on crashes. I suspect that Walter doesn't quite understand the issues here, because whenever anyone raises issues related to stuff like this, he has a tendancy to basically tell people to rerun their program - which works fantastically in the world he typically programs in (compilers) but doesn't work very well with stuff like OSes or server programs where you frequently have no clue how to replicate the problem. My guess is that Errors work they do in part because he's not used to debugging situations where a coredump being created at the point of failure the first time it happens (rather than during attempts to reproduce the problem) is what you really need. I think that the reasons that this is not a bigger problem than it is stem primarily from the fact that Errors are going to be very rare in production code unless it wasn't properly tested. So, the problem shouldn't pop up often. However, when it does, having a coredump at the site of the failure would definitely be valuable. > If the exception would be ignored the program will crash > regardless but at least there would be a stack trace that I could > rely upon instead of this unreliable and possibly corrupt state > which is good for nothing. > > This concept is a bit like color everyone with the same brush or > one shoe fits all. Where in reality it depends on the > circumstances whether it is an error or an exception. > But maybe I feel that way because currently there's a bit of a > blur regarding what's defined as Errors and Exceptions. > > Anyways I took a lot from your awesome explanations so far. > Thanks a ton! Personally, I'm increasingly of the opinion that having Errors was a mistake and that the better solution would have been to just print out the error message and stack trace right there and immediately kill the program. That would then give you a coredump exactly where you were and avoid all of the confusion about Errors being thrown but not really doing proper clean-up. I don't know why Walter decided to do it the way he did, particularly since he's made it very clear that the entire point of Errors is to indicate a fatal error in the program, that doing any clean-up at that point is dangerous, and that the program needs to terminate, not try to recover. But I don't think that changing it so that Errors terminated immediately (and thus gave you a coredump for that spot in the program) would change what's an Error and what's an Exception. Either way, Errors are for error conditions that are deemed to be unrecoverable. So, it wouldn't change the fact that trying to recover from an Error is a terrible idea. It would just make it so that Errors which occurred in programs would then be more debuggable - especially in the rare cases that they happen in production. - Jonathan M Davis