December 17, 2017
On Sunday, 17 December 2017 at 08:26:03 UTC, Jonathan M Davis wrote:
> assert(0) does indeed turn into a HLT instruction in -release mode (as does any assertion that's known to be false at compile time). It's a special case intended for marking code that's supposed to be unreachable. Without -release, failed assertions throw AssertErrors, so they're Errors not Exceptions, though I think that scope statements currently catch and then rethrow Throwable rather than Exception, which is why AssertErrors would be affected.
>
> - Jonathan M Davis


It's a little confusing, because Andrei's book says that scope(failure) guarantees statement will be executed, if and only if the current scope is exited by throwing an 'exception'.

One could *mistakingly* take that as meaning, throwing an object rooted in the 'Exception' subclass of Throwable.

Of course assert actually throws an exception too, but it's a special kind of exception rooted in the 'Error' subclass of Throwable.

Perhaps, to be clearer, Andrei's book should have said: scope(failure) guarantees statement will be executed, if and only if the current scope is exited by throwing an object that inherits from type Throwable. That would include, objects rooted in the 'Exception' subclass, as well as objects rooted in 'Error' subclass.

In which case, there's no bug in that code. It's doing what it's meant to be doing.

December 17, 2017
On Sunday, 17 December 2017 at 08:10:06 UTC, codephantom wrote:
> On Sunday, 17 December 2017 at 00:10:27 UTC, Anonymouse wrote:
>> If you return inside a scopeguard though, the exception (or error!) is swallowed. https://run.dlang.io/is/GEtQ6D
>
> The scope guard will not 'swallow' it, if you use -release mode.
>
> Which suggests to me, that assert(0) operates differently when 'not' using -release mode.
>
> My 'guess' is, that release mode issues a halt instruction, whereas in non-release mode it is just an exception like any other exception.

Apologies. I chose assert(0) just to show that it catches Errors too, so just replace it with throw new Exception and it behaves the same without opening that can of worms.
December 17, 2017
On Sunday, December 17, 2017 09:32:53 codephantom via Digitalmars-d-learn wrote:
> On Sunday, 17 December 2017 at 08:26:03 UTC, Jonathan M Davis
>
> wrote:
> > assert(0) does indeed turn into a HLT instruction in -release mode (as does any assertion that's known to be false at compile time). It's a special case intended for marking code that's supposed to be unreachable. Without -release, failed assertions throw AssertErrors, so they're Errors not Exceptions, though I think that scope statements currently catch and then rethrow Throwable rather than Exception, which is why AssertErrors would be affected.
> >
> > - Jonathan M Davis
>
> It's a little confusing, because Andrei's book says that scope(failure) guarantees statement will be executed, if and only if the current scope is exited by throwing an 'exception'.
>
> One could *mistakingly* take that as meaning, throwing an object rooted in the 'Exception' subclass of Throwable.
>
> Of course assert actually throws an exception too, but it's a special kind of exception rooted in the 'Error' subclass of Throwable.
>
> Perhaps, to be clearer, Andrei's book should have said: scope(failure) guarantees statement will be executed, if and only if the current scope is exited by throwing an object that inherits from type Throwable. That would include, objects rooted in the 'Exception' subclass, as well as objects rooted in 'Error' subclass.
>
> In which case, there's no bug in that code. It's doing what it's meant to be doing.

Well, exception vs Exception can be confusing, but there is actually no guarantee whatsoever spec-wise that scope statements work with Errors - the same goes for any other clean-up code (such as destructors or finally blocks). Some stuff like nothrow functions make it impossible, and Walter has been adamant that trying to recover from an Error is an incredibly bad idea and that programs in general are far better off exiting on an Error than trying to do any recovery from it (since by definition, when an Error is thrown, the program is in a buggy and unknown state). Given Walter's stance on it, I'm honestly a bit surprised that Error is a Throwable rather than being designed to just immediately kill the program right then an there, though under _rare_ circumstances, when you know exactly what you're doing aand catch the Error pretty much at the point it was thrown, you can get away with it for certain types of Errors like OutOfMemoryError.

However, at some point a while back, someone went into druntime and made it so that destructors, scope statements, and finally blocks run as much as possible when Errors are thrown - which isn't always but is a lot of the time. So, on some level, right now, clean-up code does get run when an Error is thrown, but it's not guaranteed and can't be guaranteed. Given Walter's stance on it, I'm surprised that druntime has never been changed so that it only does clean-up on Exceptions, but for now at least, we have a bit of a halfway mess with how Errors are handled.

Basically, code shouldn't be relying on Errors either triggering or not triggering clean-up code such as scope statements. They are only guaranteed to run when an Exception is thrown and may or may not run when any other kind of Throwable is thrown.

- Jonathan M Davis

1 2
Next ›   Last »