What is the point of nothrow?
wjoe
none at example.com
Thu Jun 14 18:11:20 UTC 2018
On Wednesday, 13 June 2018 at 20:08:06 UTC, Jonathan M Davis
wrote:
> 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
>> > 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
Good to know. The thought crossed my mind to remove nothrow from
all functions... ;)
> 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 the program is in a stable enough state to run the exception
handling mechanism to print a message and die, but not stable
enough to run a memset or writePin(11,0) before continuing
trampling forward to where the printing and dying happens ?
>> 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
that fact also means that a program which threw an Error cannot
be debugged anymore; because of invalid state you can neither
know, nor assume, that what you see in your debugger or core dump
is actually the state which led to the throw.
> improve performance by not emitting exception-handling code.
if performance matters so much I would use betterC.
'Improving' performance without profiling and such a trade-off is
a bad idea. If it were opt in - yes, I know I will get
undebuggable code on error thrown but I want or need the
performance gain, fair enough. But instead you are a victim of
that implementation whether you like it or not and you might not
even be aware about it.
>
>> 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.
>
Or any program which is interactive or where input is non
deterministic.
Out of curiosity, in case of out of memory, will the program
crash trying to throw OutOfMemoryError or is it pre-allocated
along with the memory needed to format and print the message?
And out of curiosity again, where would I find this place where
the printing and terminating occurs ?
> 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.
>
It's not possible to catch every bug before shipping. And there's
plenty of critical one in software of every developer.
And because software was thoroughly tested before shipping, the
remaining bugs are tricky to catch and are most likely not easy
to reproduce. So a core dump might be all you've got and if that
shows invalid state of the program, did a few things here but not
there..I wouldn't want to be the sorry sod having to fix that bug.
On the other hand one could just wave it off, because why bother,
happens too rarely, or blame the user of doing something wrong.
That works, too.
> 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.
>
Aborting with an error code would be sufficient. No need to print
anything.
A backtrace can be obtained in the debugger.
> 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.
No it wouldn't but not everything declared or treated as an error
in D is one.
There should be only a few and everything else should be an
Exception.
More information about the Digitalmars-d-learn
mailing list