digitalmars.D - scope() statements and return
- Shammah Chancellor (4/4) Oct 02 2014 Per the documentation (http://dlang.org/statement.html) scope
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/10) Oct 02 2014 Can you show a piece of code. The following quote says "may not exit
- Shammah Chancellor (2/4) Oct 02 2014 Derp. I did not see that. I was looking at the grammar on the top.
- deadalnix (3/18) Oct 02 2014 The throw thing is rather stupid, as the scope statement can call
- ketmar via Digitalmars-d (5/7) Oct 02 2014 that's why you'd better use collectException() there, i presume. ;-)
- Jakob Ovrum (4/13) Oct 03 2014 No, just like destructors can throw, scope statements can throw
- Andrei Alexandrescu (2/4) Oct 03 2014 Seems to me all these restrictions should be lifted. -- Andrei
- H. S. Teoh via Digitalmars-d (58/63) Oct 03 2014 Please don't. It will lead to pathological behaviour. For example:
- Andrei Alexandrescu (8/69) Oct 03 2014 2
- deadalnix (5/7) Oct 03 2014 True for return, but throw is a stupid limitation( as it do not
- ketmar via Digitalmars-d (20/23) Oct 03 2014 scope(exit) {
- Ola Fosheim Grostad (15/23) Oct 03 2014 It is tricky if the throw implies that the caller to the cleanup
- ketmar via Digitalmars-d (6/8) Oct 03 2014 On Sat, 04 Oct 2014 03:46:35 +0000
- Ola Fosheim Grostad (7/13) Oct 03 2014 Should or should not, you have to make do with what you get from
- ketmar via Digitalmars-d (7/12) Oct 03 2014 On Sat, 04 Oct 2014 04:54:38 +0000
- Ola Fosheim Grostad (4/11) Oct 03 2014 I dont disagree, but the language spec says that you cannot catch
- ketmar via Digitalmars-d (9/14) Oct 03 2014 On Sat, 04 Oct 2014 05:22:10 +0000
- Ola Fosheim Grostad (3/9) Oct 03 2014 Why should these two cases be treated different? Makes no sense,
- ketmar via Digitalmars-d (9/10) Oct 03 2014 On Sat, 04 Oct 2014 05:37:14 +0000
- Ola Fosheim Grostad (6/15) Oct 03 2014 If finally does imply nothrow then the try-block implies it too.
- ketmar via Digitalmars-d (10/12) Oct 03 2014 On Sat, 04 Oct 2014 05:58:47 +0000
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (4/7) Oct 04 2014 Triathlon isn't really my thing...
- Andrei Alexandrescu (3/15) Oct 04 2014 There's no interesting way to check this because functions don't list
- ketmar via Digitalmars-d (13/15) Oct 04 2014 On Sat, 04 Oct 2014 14:48:26 -0700
- Timon Gehr (4/19) Oct 07 2014 What's the point anyway?
- ketmar via Digitalmars-d (3/4) Oct 07 2014 non-final try/catch will not make function "nothrow".
- Timon Gehr (6/10) Oct 07 2014 void doStuff(){ }
- ketmar via Digitalmars-d (6/8) Oct 07 2014 i'm talking about my proposal, where non-final try/catch will not make
- Timon Gehr (16/25) Oct 07 2014 import core.exception;
- ketmar via Digitalmars-d (11/37) Oct 07 2014 that's not the same as 'final try': anything that is not
- deadalnix (4/33) Oct 03 2014 Write this in sepeareted scope statement?. problem solved.
- Ola Fosheim Grostad (4/5) Oct 03 2014 Exception chaining just means that you build a linked list
- ketmar via Digitalmars-d (12/13) Oct 03 2014 i don't agree. it makes excessive noise for nothing. and it breaking
- Andrei Alexandrescu (2/8) Oct 03 2014 Yah throw would be nice and helpful. -- Andrei
- Andrei Alexandrescu (3/8) Oct 04 2014 Yah, nonlocal returns are odd but throw should be perfectly fine (and
- Shammah Chancellor (7/17) Oct 04 2014 They were removed because they stop the propigation of Errors when and
- Shammah Chancellor (19/43) Oct 03 2014 That should return 1 as the return 1 is the last thing to execute.
- H. S. Teoh via Digitalmars-d (41/57) Oct 03 2014 [...]
- Shammah Chancellor (13/79) Oct 04 2014 Didn't miss anything. I was responding to Andrei such that he might
- monarch_dodra (6/19) Oct 05 2014 Isn't this the "should scope(exit/failure) catch Error" issue
- ketmar via Digitalmars-d (4/6) Oct 05 2014 'cause scope(exit) keeps the promise to execute cleanup code before
- monarch_dodra (7/15) Oct 05 2014 Promises hold provided the precondition your program is in a
- ketmar via Digitalmars-d (5/8) Oct 05 2014 so Error should not be catchable and should crash immidiately, without
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (22/27) Oct 05 2014 I find it strange if you cannot recover from out-of-memory-error.
- Dicebot (4/5) Oct 05 2014 Yes. http://dlang.org/phobos/object.html#.Throwable.next
- Andrei Alexandrescu (2/6) Oct 05 2014 What harm does it do? -- Andrei
- Dicebot (8/16) Oct 05 2014 Good chunk of issues with pre-allocated exceptions (and possible
- Walter Bright (3/17) Oct 06 2014 FWIW, I'm skeptical as well of the value of chaining relative to its cos...
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (7/9) Oct 06 2014 Python 3 has two fields: "__cause__" and "__context__".
- Andrei Alexandrescu (5/26) Oct 06 2014 It's one of those designs in which there's little room to turn. We
- monarch_dodra (22/55) Oct 06 2014 Well, then again, even that promise isn't really held.
- Andrei Alexandrescu (3/12) Oct 06 2014 That's code under library/user control, I'm talking about the
- monarch_dodra (24/39) Oct 06 2014 Right. but if correct usage is so cumbersome no one does it
- Andrei Alexandrescu (10/47) Oct 06 2014 Only if it needs to save that information. As far as the core language
- monarch_dodra (7/14) Oct 07 2014 On Monday, 6 October 2014 at 17:12:00 UTC, Jakob Ovrum wrote:
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (10/14) Oct 07 2014 I've never used it myself in real code, but I think the "swallow
- Andrei Alexandrescu (3/7) Oct 07 2014 No. But that doesn't mean anything; all uses of exceptions I know of are...
- Regan Heath (18/25) Oct 08 2014 I have a couple of examples here in front of me. This is in C#...
- Jakob Ovrum (15/17) Oct 06 2014 I use explicit chaining in a couple of my libraries, i.e. code
- deadalnix (2/19) Oct 06 2014 I think this is supposed to chain the other way around.
- deadalnix (5/9) Oct 06 2014 Note that if we reverse the chaining (like java does), then the
- Andrei Alexandrescu (3/12) Oct 06 2014 I knew Python has chaining but not Java. Got a reference handy? My
- deadalnix (3/10) Oct 07 2014 Yes there is no language magic to it in java. It is by convention.
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (9/11) Oct 05 2014 Hm, so the next field is used for two different purposes? Both
- deadalnix (11/23) Oct 05 2014 I know of several cases where this trick was used and it turned
- Ola Fosheim Grostad (6/12) Oct 05 2014 You can throw a fatal error if you run out of memory twice. You
- monarch_dodra (6/17) Oct 05 2014 Don't put words in my mouth. Also, Errors do only partial stack
- ketmar via Digitalmars-d (8/9) Oct 05 2014 if it looks like a duck, if it quacks like a duck, if it can be catched
- Dicebot (11/13) Oct 05 2014 It is not guaranteed by spec (I guess this was added to allow
- ketmar via Digitalmars-d (11/14) Oct 05 2014 than it was done very wrong. it's ok to have some arcane chain of
- Shammah Chancellor (6/26) Oct 05 2014 It doesn't "catch" the error. Propigation should continue as normal.
- monarch_dodra (14/16) Oct 06 2014 Right, it only "intercepts, cleanups, and rethrows". But the
- Steven Schveighoffer (8/13) Oct 06 2014 The above smells to me like it should be invalid. Specifically, the
- David Nadlinger (5/11) Oct 03 2014 Unless we have very good reason, the same restrictions as for
- Shammah Chancellor (2/13) Oct 03 2014 They do.
Per the documentation (http://dlang.org/statement.html) scope statements are not precluded from returning, but DMD does not allow for it. Should the documentation be updated? -S
Oct 02 2014
On 10/02/2014 07:17 PM, Shammah Chancellor wrote:Per the documentation (http://dlang.org/statement.html) scope statements are not precluded from returning, but DMD does not allow for it. Should the documentation be updated? -SCan you show a piece of code. The following quote says "may not exit with [...] return": "A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto." Ali
Oct 02 2014
On 2014-10-03 03:23:24 +0000, Ali ehreli said:A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a gotoDerp. I did not see that. I was looking at the grammar on the top.
Oct 02 2014
On Friday, 3 October 2014 at 03:23:25 UTC, Ali Çehreli wrote:On 10/02/2014 07:17 PM, Shammah Chancellor wrote:The throw thing is rather stupid, as the scope statement can call arbitrary function that can itself throw.Per the documentation (http://dlang.org/statement.html) scope statements are not precluded from returning, but DMD does not allow for it. Should the documentation be updated? -SCan you show a piece of code. The following quote says "may not exit with [...] return": "A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto." Ali
Oct 02 2014
On Fri, 03 Oct 2014 04:40:53 +0000 deadalnix via Digitalmars-d <digitalmars-d puremagic.com> wrote:The throw thing is rather stupid, as the scope statement can call=20 arbitrary function that can itself throw.that's why you'd better use collectException() there, i presume. ;-) btw: shouldn't compiler check and reject code that calls no-nothrow functions in scope(...)? bug/ER?
Oct 02 2014
On Friday, 3 October 2014 at 04:52:24 UTC, ketmar via Digitalmars-d wrote:On Fri, 03 Oct 2014 04:40:53 +0000 deadalnix via Digitalmars-d <digitalmars-d puremagic.com> wrote:No, just like destructors can throw, scope statements can throw too. That's why we have exception chaining.The throw thing is rather stupid, as the scope statement can call arbitrary function that can itself throw.that's why you'd better use collectException() there, i presume. ;-) btw: shouldn't compiler check and reject code that calls no-nothrow functions in scope(...)? bug/ER?
Oct 03 2014
On 10/2/14, 8:23 PM, Ali Çehreli wrote:"A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto."Seems to me all these restrictions should be lifted. -- Andrei
Oct 03 2014
On Fri, Oct 03, 2014 at 10:50:39AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:On 10/2/14, 8:23 PM, Ali Çehreli wrote:Please don't. It will lead to pathological behaviour. For example: int func() { scope(exit) return 1; return 0; } What does func() return? Better yet: int func() { scope(exit) return 1; scope(exit) return 2; return 0; } Worse yet: // What does this function do? What *should* it do?? int func() { scope(success) throw new Exception(""); scope(failure) return 1; return 0; } And: int func() { hahaha: scope(exit) goto hahaha; return 1; } Or: int func() { foreach (i; 0..10) { scope(exit) break; scope(exit) continue; return i; // hahahahahaha } return i; } And do we really want to get into this one: struct S { void opApply(scope void delegate(int) loopBody) { foreach (i; 0..10) { scope(success) continue; auto rc = loopBody(i); if (rc != 0) return rc; // ORLY?! } } } void main() { foreach (i; S.init) { scope(failure) continue; // what does this do? throw new Exception(""); } } T -- Береги платье снову, а здоровье смолоду."A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto."Seems to me all these restrictions should be lifted. -- Andrei
Oct 03 2014
On 10/3/14, 11:18 AM, H. S. Teoh via Digitalmars-d wrote:On Fri, Oct 03, 2014 at 10:50:39AM -0700, Andrei Alexandrescu via Digitalmars-d wrote:1On 10/2/14, 8:23 PM, Ali Çehreli wrote:Please don't. It will lead to pathological behaviour. For example: int func() { scope(exit) return 1; return 0; } What does func() return?"A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto."Seems to me all these restrictions should be lifted. -- AndreiBetter yet: int func() { scope(exit) return 1; scope(exit) return 2; return 0; }2Worse yet: // What does this function do? What *should* it do?? int func() { scope(success) throw new Exception(""); scope(failure) return 1; return 0; }1And: int func() { hahaha: scope(exit) goto hahaha; return 1; }infinite loopOr: int func() { foreach (i; 0..10) { scope(exit) break; scope(exit) continue; return i; // hahahahahaha } return i; }compile errorAnd do we really want to get into this one: struct S { void opApply(scope void delegate(int) loopBody) { foreach (i; 0..10) { scope(success) continue; auto rc = loopBody(i); if (rc != 0) return rc; // ORLY?! } } } void main() { foreach (i; S.init) { scope(failure) continue; // what does this do? throw new Exception(""); } }I guess I'm convinced it adds more complication than expressiveness! Andrei
Oct 03 2014
On Friday, 3 October 2014 at 19:35:21 UTC, Andrei Alexandrescu wrote:I guess I'm convinced it adds more complication than expressiveness!True for return, but throw is a stupid limitation( as it do not prevent the scope to throw at all, simply forc to hide it, which is only worse).
Oct 03 2014
On Sat, 04 Oct 2014 03:01:14 +0000 deadalnix via Digitalmars-d <digitalmars-d puremagic.com> wrote:True for return, but throw is a stupid limitation( as it do not=20 prevent the scope to throw at all, simply forc to hide it, which=20 is only worse).scope(exit) { some-cleanup-code thisCanThrow(); some-more-cleanup-code } and what we should do with "some-more-cleanup-code" if "thisCanThrow" throws? it's breaks the promise that all cleanup code was executed prior to exiting. if i'm writing `collectException(thisCanThrow());`, i'm making my intents clear: "ok, i know that it can throw and i'm fully responsible to ignoring that here". yet silently allowing functions that throws in this context is disasterous, as it nullifies the promise on cleanup code. then i have to write such abominations: scope(exit) { some-cleanup-code scope(exit) some-more-cleanup-code; thisCanThrow(); } WUT?! this is hard to read and unnecessary complicated.
Oct 03 2014
On Saturday, 4 October 2014 at 03:21:23 UTC, ketmar via Digitalmars-d wrote:scope(exit) { some-cleanup-code thisCanThrow(); some-more-cleanup-code } and what we should do with "some-more-cleanup-code" if "thisCanThrow" throws?It is tricky if the throw implies that the caller to the cleanup should retry because of a timeout/deadlock, so the programmer have to analyze it and catch it if a retry is implied. So you need to catch in scope(exit) and check the coverage during semantic analysis. The alternatives are: 1. formally forbid throwing in all functions that closes/frees resources and use return values instead, but that is inconsistent with having exceptions in the first place... 2. not free resources, but use a manager object that frees them in the background, but that defeats having scope(exit) 3. remove exceptions from the language. Point 3 sounds nice. :-)
Oct 03 2014
On Sat, 04 Oct 2014 03:46:35 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:It is tricky if the throw implies that the caller to the cleanup=20 should retry because of a timeout/deadlockit shouldn't. exception during cleanup means "oh, i can't! i really-really-really can't!", not "ok, i'm busy, try again later." if some badly designed API does that -- write a wrapper.
Oct 03 2014
On Saturday, 4 October 2014 at 04:29:06 UTC, ketmar via Digitalmars-d wrote:Should or should not, you have to make do with what you get from libraries. Network being temporarily unavailable is a good reason to throw when freeing a networked resource... Exceptions are made for recovery/retry/rollback.It is tricky if the throw implies that the caller to the cleanup should retry because of a timeout/deadlockit shouldn't. exception during cleanup means "oh, i can't! i really-really-really can't!", not "ok, i'm busy, try again later."if some badly designed API does that -- write a wrapper.So you need semantic analysis to ensure nothrow.
Oct 03 2014
On Sat, 04 Oct 2014 04:54:38 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:Should or should not, you have to make do with what you get from=20 libraries.wrapper is the answer.Network being temporarily unavailable is a good reason=20 to throw when freeing a networked resource...that means "oh, i really-really-really can't!" there is no guarantees that network will be up again soon.So you need semantic analysis to ensure nothrow.we have it, and we have that nice "nothrow" attribute.
Oct 03 2014
On Saturday, 4 October 2014 at 05:05:00 UTC, ketmar via Digitalmars-d wrote:On Sat, 04 Oct 2014 04:54:38 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:I dont disagree, but the language spec says that you cannot catch in a finally block... (which is the same as scope(exit).Should or should not, you have to make do with what you get from libraries.wrapper is the answer.
Oct 03 2014
On Sat, 04 Oct 2014 05:22:10 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:and... wrapper is the answer! ;-) void myWrapper () nothrow { try throwItAtMe(); catch (LovelyException) {} } scope(exit) myWrapper(); this is perfectly legal, as we not cathcing anything in scope(exit).I dont disagree, but the language spec says that you cannot catch=20 in a finally block... (which is the same as scope(exit).Should or should not, you have to make do with what you get=20 from libraries.wrapper is the answer.
Oct 03 2014
On Saturday, 4 October 2014 at 05:33:29 UTC, ketmar via Digitalmars-d wrote:void myWrapper () nothrow { try throwItAtMe(); catch (LovelyException) {} } scope(exit) myWrapper(); this is perfectly legal, as we not cathcing anything in scope(exit).Why should these two cases be treated different? Makes no sense,
Oct 03 2014
On Sat, 04 Oct 2014 05:37:14 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:Why should these two cases be treated different? Makes no sense,'cause `MyWrapper` promises to nothrow. you can't make such promise for try-block. i.e. `MyWrapper` promises that the only exception that can be thrown is `LovelyException`, and it's catched, thus `MyWrapper` is marked "nothrow". you can't attach such mark to try/catch, even if you know for sure that you catched 'em all. it's a matter of style.
Oct 03 2014
On Saturday, 4 October 2014 at 05:54:20 UTC, ketmar via Digitalmars-d wrote:,'cause `MyWrapper` promises to nothrow. you can't make such promise for try-block.If finally does imply nothrow then the try-block implies it too. No difference from a wrapper.i.e. `MyWrapper` promises that the only exception that can be thrown is `LovelyException`, and it's catched, thus `MyWrapper` is marked "nothrow". you can't attach such mark to try/catch, even if you know for sure that you catched 'em all. it's a matter of style.Nah, it is a matter of ad hoc design and implementation that needs more rigour.
Oct 03 2014
On Sat, 04 Oct 2014 05:58:47 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:Nah, it is a matter of ad hoc design and implementation that=20 needs more rigour.something like 'final try' can be fun. 'try' says that it can catch only some kinds of exceptions, and 'final try' promises that there will be no exceptions that aren't in catch() block. besides, any exception that 'final try' is not catching should abort the process. do you mind to fill ER? it will be rejected, but hey, we can start a little competiion here! ;-)
Oct 03 2014
On Saturday, 4 October 2014 at 06:28:52 UTC, ketmar via Digitalmars-d wrote:do you mind to fill ER? it will be rejected, but hey, we can start a little competiion here! ;-)Triathlon isn't really my thing... So I am only participating in the patching-competition. :-)
Oct 04 2014
On 10/3/14, 11:28 PM, ketmar via Digitalmars-d wrote:On Sat, 04 Oct 2014 05:58:47 +0000 Ola Fosheim Grostad via Digitalmars-d <digitalmars-d puremagic.com> wrote:There's no interesting way to check this because functions don't list the exceptions they might throw (like Java does). -- AndreiNah, it is a matter of ad hoc design and implementation that needs more rigour.something like 'final try' can be fun. 'try' says that it can catch only some kinds of exceptions, and 'final try' promises that there will be no exceptions that aren't in catch() block. besides, any exception that 'final try' is not catching should abort the process. do you mind to fill ER? it will be rejected, but hey, we can start a little competiion here! ;-)
Oct 04 2014
On Sat, 04 Oct 2014 14:48:26 -0700 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:There's no interesting way to check this because functions don't list=20 the exceptions they might throw (like Java does). -- Andreisure there is no way to check. this 'final try' helper is required exactly 'cause compiler can't do necessary checks, and programmer can assure compiler that "it's ok, we'll catching 'em all here!" this way 'try/catch' will not be "nothrow", only 'final try/catch'. and there will be *nothing* that can be catched outside of 'final try/catch'. i.e. if something was not catched in 'final', it's a fatal bug. crash-boom-band, we are dead. but i don't want to create ER, 'cause it will be rejected. it implies code breaking ("simple" try/catch can't be used in 'nothrow' functions anymore), and ERs with code breaking feature have no chances.
Oct 04 2014
On 10/05/2014 08:01 AM, ketmar via Digitalmars-d wrote:On Sat, 04 Oct 2014 14:48:26 -0700 Andrei Alexandrescu via Digitalmars-d <digitalmars-d puremagic.com> wrote:What's the point anyway? try{ ... } catch assert(0);There's no interesting way to check this because functions don't list the exceptions they might throw (like Java does). -- Andreisure there is no way to check. this 'final try' helper is required exactly 'cause compiler can't do necessary checks, and programmer can assure compiler that "it's ok, we'll catching 'em all here!" this way 'try/catch' will not be "nothrow", only 'final try/catch'. and there will be *nothing* that can be catched outside of 'final try/catch'. i.e. if something was not catched in 'final', it's a fatal bug. crash-boom-band, we are dead. but i don't want to create ER, 'cause it will be rejected. it implies code breaking ("simple" try/catch can't be used in 'nothrow' functions anymore), and ERs with code breaking feature have no chances.
Oct 07 2014
On Tue, 07 Oct 2014 14:59:52 +0200 Timon Gehr via Digitalmars-d <digitalmars-d puremagic.com> wrote:What's the point anyway?non-final try/catch will not make function "nothrow".
Oct 07 2014
On 10/07/2014 03:57 PM, ketmar via Digitalmars-d wrote:On Tue, 07 Oct 2014 14:59:52 +0200 Timon Gehr via Digitalmars-d <digitalmars-d puremagic.com> wrote:void doStuff(){ } void main() nothrow{ try{ doStuff(); } catch assert(0); }What's the point anyway?non-final try/catch will not make function "nothrow".
Oct 07 2014
On Tue, 07 Oct 2014 16:08:33 +0200 Timon Gehr via Digitalmars-d <digitalmars-d puremagic.com> wrote:i'm talking about my proposal, where non-final try/catch will not make function nothrow, only 'final try' will do. and anything that not catched in this 'final' will abort the program immediately, without any tries to do unwinding or executing scope() statements.What's the point anyway?non-final try/catch will not make function "nothrow".
Oct 07 2014
On 10/07/2014 04:23 PM, ketmar via Digitalmars-d wrote:On Tue, 07 Oct 2014 16:08:33 +0200 Timon Gehr via Digitalmars-d <digitalmars-d puremagic.com> wrote:import core.exception; void doStuff(){ } void main() nothrow{ try{ doStuff(); } catch(UnicodeException){ } } Error: function D main 'main' is nothrow yet may throwWhat's the point anyway?non-final try/catch will not make function "nothrow".i'm talking about my proposal, where non-final try/catch will not make function nothrow, only 'final try' will do.I.e. additional annotation overhead without a point?and anything that not catched in this 'final' will abort the program immediately, without any tries to do unwinding or executing scope() statements.import core.stdc.stdlib; void doStuff(){ throw new Exception(""); } void main() nothrow{ scope(exit) assert(0); try{ doStuff(); } catch(Exception){ exit(2); } }
Oct 07 2014
On Tue, 07 Oct 2014 16:34:12 +0200 Timon Gehr via Digitalmars-d <digitalmars-d puremagic.com> wrote:import core.exception; =20 void doStuff(){ } =20 void main() nothrow{ try{ doStuff(); } catch(UnicodeException){ } } =20 Error: function D main 'main' is nothrow yet may throwthat's not the same as 'final try': anything that is not UnicodeException or it's descendant will pass thru. for 'final try' anything other will crash the program immediately. no, 'assert(0)' is not the same.with a point. you even quoted it.i'm talking about my proposal, where non-final try/catch will not make function nothrow, only 'final try' will do.I.e. additional annotation overhead without a point?i see *alot* of overhead here. and 'exit()', which will not show what exception was thrown. yes, we can print this info manually -- adding even more overhead. with 'final try' reader immediately recognizes writer's intentions.and anything that not catched in this 'final' will abort the program immediately, without any tries to do unwinding or executing scope() statements.=20 import core.stdc.stdlib; =20 void doStuff(){ throw new Exception(""); } =20 void main() nothrow{ scope(exit) assert(0); try{ doStuff(); } catch(Exception){ exit(2); } }
Oct 07 2014
On Saturday, 4 October 2014 at 03:21:23 UTC, ketmar via Digitalmars-d wrote:On Sat, 04 Oct 2014 03:01:14 +0000 deadalnix via Digitalmars-d <digitalmars-d puremagic.com> wrote:Write this in sepeareted scope statement?. problem solved. Also, we have exception chaining, so that's all good.True for return, but throw is a stupid limitation( as it do not prevent the scope to throw at all, simply forc to hide it, which is only worse).scope(exit) { some-cleanup-code thisCanThrow(); some-more-cleanup-code } and what we should do with "some-more-cleanup-code" if "thisCanThrow" throws? it's breaks the promise that all cleanup code was executed prior to exiting. if i'm writing `collectException(thisCanThrow());`, i'm making my intents clear: "ok, i know that it can throw and i'm fully responsible to ignoring that here". yet silently allowing functions that throws in this context is disasterous, as it nullifies the promise on cleanup code. then i have to write such abominations: scope(exit) { some-cleanup-code scope(exit) some-more-cleanup-code; thisCanThrow(); } WUT?! this is hard to read and unnecessary complicated.
Oct 03 2014
On Saturday, 4 October 2014 at 04:47:46 UTC, deadalnix wrote:Also, we have exception chaining, so that's all good.Exception chaining just means that you build a linked list recording the history when rethrowing a different type of exception in a catch block. How does that help?
Oct 03 2014
On Sat, 04 Oct 2014 04:47:44 +0000 deadalnix via Digitalmars-d <digitalmars-d puremagic.com> wrote:Write this in sepeareted scope statement?. problem solved.i don't agree. it makes excessive noise for nothing. and it breaking the implied promise "all cleanup code will be executed on exit". it's easy to miss something that can throw in scope(...). so the only other option is to write this noisy code: scope(exit) firstCall(); scope(exit) secondCall(); scope(exit) thirdCall(); ...and so on. and double-check if everything was really executed -- just in case. 'cause there is no promise to execute cleanup code anymore.
Oct 03 2014
"deadalnix" <deadalnix gmail.com> wrote:On Friday, 3 October 2014 at 19:35:21 UTC, Andrei Alexandrescu wrote:Yah throw would be nice and helpful. -- AndreiI guess I'm convinced it adds more complication than > expressiveness!True for return, but throw is a stupid limitation( as it do not prevent the scope to throw at all, simply forc to hide it, which is only worse).
Oct 03 2014
On 10/3/14, 8:01 PM, deadalnix wrote:On Friday, 3 October 2014 at 19:35:21 UTC, Andrei Alexandrescu wrote:Yah, nonlocal returns are odd but throw should be perfectly fine (and good to have). -- AndreiI guess I'm convinced it adds more complication than expressiveness!True for return, but throw is a stupid limitation( as it do not prevent the scope to throw at all, simply forc to hide it, which is only worse).
Oct 04 2014
On 2014-10-04 21:44:43 +0000, Andrei Alexandrescu said:On 10/3/14, 8:01 PM, deadalnix wrote:They were removed because they stop the propigation of Errors when and if they were to throw. This was already discussed quite a bit months ago. My original message was not intended to respawn the debate. Here's the dbug: https://issues.dlang.org/show_bug.cgi?id=11574 I'm not sure why it's still open actually. -ShammahOn Friday, 3 October 2014 at 19:35:21 UTC, Andrei Alexandrescu wrote:Yah, nonlocal returns are odd but throw should be perfectly fine (and good to have). -- AndreiI guess I'm convinced it adds more complication than expressiveness!True for return, but throw is a stupid limitation( as it do not prevent the scope to throw at all, simply forc to hide it, which is only worse).
Oct 04 2014
On 2014-10-03 19:35:31 +0000, Andrei Alexandrescu said:That should return 1 as the return 1 is the last thing to execute. SDC currently doesn't disallow this and correctly produces 1. It'll be lowered as such: int foo2() { try { try { return 0; } finally { return 2; } } finally { return 1; } }Better yet: int func() { scope(exit) return 1; scope(exit) return 2; return 0; }2This throws an exception, as it's already outside of the scope(failure) block and into the finally for success; -SWorse yet: // What does this function do? What *should* it do?? int func() { scope(success) throw new Exception(""); scope(failure) return 1; return 0; }1
Oct 03 2014
On Sat, Oct 04, 2014 at 01:08:38AM -0400, Shammah Chancellor via Digitalmars-d wrote:On 2014-10-03 19:35:31 +0000, Andrei Alexandrescu said:[...][...] And if you switched the two scope statements? I think you guys are missing the point... The point is that it's ridiculous for the function to return one thing, only for the scope statement to modify that return value after the fact in a way that totally obfuscates the code. int func() { lots(); of(); scope(exit) return 1; code(); inBetween(); // What does this function return? Yes, "obviously" it // returns 1. Right. return 0; } Similarly, allowing scope to do arbitrary things will easily turn your loops into spaghetti code: foreach (i; 0 .. 10) { scope(exit) break; scope(success) continue; if (i==5) break; // Yeah right, this doesn't actually break // (even though it's totally broken :-P) scope(failure) return; if (i==8) throw new Exception(); // Yeah right, this is just a dainbramaged way // of breaking the loop } writeln("You know I actually get run?"); The only use of allowing these disruptive flow control constructs in scope statements, that I can see, is to facilitate in writing entries for the International Obfuscated D Code Contest. T -- Маленькие детки - маленькие бедки.This throws an exception, as it's already outside of the scope(failure) block and into the finally for success;Worse yet: // What does this function do? What *should* it do?? int func() { scope(success) throw new Exception(""); scope(failure) return 1; return 0; }1
Oct 03 2014
On 2014-10-04 06:09:39 +0000, H. S. Teoh via Digitalmars-d said:On Sat, Oct 04, 2014 at 01:08:38AM -0400, Shammah Chancellor via Digitalmars-d wrote:Didn't miss anything. I was responding to Andrei such that he might think it's not so straightforward to evaluate that code. I am with you on this. It was my original complaint months ago that resulted in this being disallowed behavior. Specifically because you could stop error propigation by accident even though you did not intend to prevent their propigation. e.g: int main() { scope(exit) return 0; assert(false, "whoops!"); } -SOn 2014-10-03 19:35:31 +0000, Andrei Alexandrescu said:[...][...] And if you switched the two scope statements? I think you guys are missing the point... The point is that it's ridiculous for the function to return one thing, only for the scope statement to modify that return value after the fact in a way that totally obfuscates the code. int func() { lots(); of(); scope(exit) return 1; code(); inBetween(); // What does this function return? Yes, "obviously" it // returns 1. Right. return 0; } Similarly, allowing scope to do arbitrary things will easily turn your loops into spaghetti code: foreach (i; 0 .. 10) { scope(exit) break; scope(success) continue; if (i==5) break; // Yeah right, this doesn't actually break // (even though it's totally broken :-P) scope(failure) return; if (i==8) throw new Exception(); // Yeah right, this is just a dainbramaged way // of breaking the loop } writeln("You know I actually get run?"); The only use of allowing these disruptive flow control constructs in scope statements, that I can see, is to facilitate in writing entries for the International Obfuscated D Code Contest. TThis throws an exception, as it's already outside of the scope(failure) block and into the finally for success;Worse yet: // What does this function do? What *should* it do?? int func() { scope(success) throw new Exception(""); scope(failure) return 1; return 0; }1
Oct 04 2014
On Saturday, 4 October 2014 at 18:42:05 UTC, Shammah Chancellor wrote:Didn't miss anything. I was responding to Andrei such that he might think it's not so straightforward to evaluate that code. I am with you on this. It was my original complaint months ago that resulted in this being disallowed behavior. Specifically because you could stop error propigation by accident even though you did not intend to prevent their propigation. e.g: int main() { scope(exit) return 0; assert(false, "whoops!"); } -SIsn't this the "should scope(exit/failure) catch Error" issue though? In theory, you should seldom ever catch Errors. I don't understand why "scope(exit)" are catching them.
Oct 05 2014
On Sun, 05 Oct 2014 11:28:59 +0000 monarch_dodra via Digitalmars-d <digitalmars-d puremagic.com> wrote:In theory, you should seldom ever catch Errors. I don't=20 understand why "scope(exit)" are catching them.'cause scope(exit) keeps the promise to execute cleanup code before exiting code block?
Oct 05 2014
On Sunday, 5 October 2014 at 12:36:30 UTC, ketmar via Digitalmars-d wrote:On Sun, 05 Oct 2014 11:28:59 +0000 monarch_dodra via Digitalmars-d <digitalmars-d puremagic.com> wrote:Promises hold provided the precondition your program is in a valid state. Having an Error invalidates that precondition, hence voids that promise. RAII also makes the promise, but you don't see Errors giving much of a fuck about that.In theory, you should seldom ever catch Errors. I don't understand why "scope(exit)" are catching them.'cause scope(exit) keeps the promise to execute cleanup code before exiting code block?
Oct 05 2014
On Sun, 05 Oct 2014 14:53:37 +0000 monarch_dodra via Digitalmars-d <digitalmars-d puremagic.com> wrote:Promises hold provided the precondition your program is in a=20 valid state. Having an Error invalidates that precondition, hence=20 voids that promise.so Error should not be catchable and should crash immidiately, without any unwinding. as long as Errors are just another kind of exception, the promise must be kept.
Oct 05 2014
On Sunday, 5 October 2014 at 15:03:08 UTC, ketmar via Digitalmars-d wrote:so Error should not be catchable and should crash immidiately, without any unwinding. as long as Errors are just another kind of exception, the promise must be kept.I find it strange if you cannot recover from out-of-memory-error. The common trick is to preallocate a bulk of memory, then free it when you throw the out of memory exception so that you can unwind. When destroying the out-of-memory-object you need to reallocate the bulk of memory. I also find the D terminology confusing, one should avoid redefining terms. Does D have exception chaining? The language spec seems to imply that finally swallows thrown exceptions if another exception A is running and stuff them in a bag in the A exception. This is kind of dangerous since you hide potentially serious exceptions this way and it is not what I think of as exception chaining. To me exception chaining is preserve the exception chain on re-throws (like preserving the call stack). So yep, ketmar, you are right. You should probably not be able to throw in finally without catching it, and you should be able to do a catch all without wrapping it up in a function. The alternatives such as the mechanics described in the language specs will lead to unreliable exception handling and poor recovery strategies IMO.
Oct 05 2014
On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:Does D have exception chaining?Though it seems to do more harm then good so far.
Oct 05 2014
On 10/5/14, 9:42 AM, Dicebot wrote:On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:What harm does it do? -- AndreiDoes D have exception chaining?Though it seems to do more harm then good so far.
Oct 05 2014
On Sunday, 5 October 2014 at 17:03:07 UTC, Andrei Alexandrescu wrote:On 10/5/14, 9:42 AM, Dicebot wrote:Good chunk of issues with pre-allocated exceptions (and possible cycles in reference counted ones) comes from the chanining possibility. At the same time I have yet to see it actively used as a feature. Doesn't mean it is bad thing, just not used wide enough to compensate for trouble right now.On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:What harm does it do? -- AndreiDoes D have exception chaining?Though it seems to do more harm then good so far.
Oct 05 2014
On 10/5/2014 10:09 AM, Dicebot wrote:On Sunday, 5 October 2014 at 17:03:07 UTC, Andrei Alexandrescu wrote:FWIW, I'm skeptical as well of the value of chaining relative to its cost in complexity.On 10/5/14, 9:42 AM, Dicebot wrote:Good chunk of issues with pre-allocated exceptions (and possible cycles in reference counted ones) comes from the chanining possibility. At the same time I have yet to see it actively used as a feature. Doesn't mean it is bad thing, just not used wide enough to compensate for trouble right now.On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:What harm does it do? -- AndreiDoes D have exception chaining?Though it seems to do more harm then good so far.
Oct 06 2014
On Monday, 6 October 2014 at 07:28:22 UTC, Walter Bright wrote:FWIW, I'm skeptical as well of the value of chaining relative to its cost in complexity.Python 3 has two fields: "__cause__" and "__context__". The cause field is used for explicit chaining on re-throws. Can be useful for diagnostics and is trouble free. The context field is used for preserving exceptions that are unfortunately overruled by subsequent throws. Which can lead to missed clean-up handling. :-/
Oct 06 2014
On 10/6/14, 12:27 AM, Walter Bright wrote:On 10/5/2014 10:09 AM, Dicebot wrote:It's one of those designs in which there's little room to turn. We wanted to (a) allow destructors to throw, (b) conserve information. Offering access to all exceptions caught was a natural consequence. -- AndreiOn Sunday, 5 October 2014 at 17:03:07 UTC, Andrei Alexandrescu wrote:FWIW, I'm skeptical as well of the value of chaining relative to its cost in complexity.On 10/5/14, 9:42 AM, Dicebot wrote:Good chunk of issues with pre-allocated exceptions (and possible cycles in reference counted ones) comes from the chanining possibility. At the same time I have yet to see it actively used as a feature. Doesn't mean it is bad thing, just not used wide enough to compensate for trouble right now.On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:What harm does it do? -- AndreiDoes D have exception chaining?Though it seems to do more harm then good so far.
Oct 06 2014
On Monday, 6 October 2014 at 13:48:07 UTC, Andrei Alexandrescu wrote:On 10/6/14, 12:27 AM, Walter Bright wrote:Well, then again, even that promise isn't really held. If your "catch" throws an exception, then the new exception simply "squashes" replaces the old one: //---- catch (Exception e) { thisMightThrow(); //Lose "e" here throw e; } //---- I've seen literally no-one ever chain exceptions once one has been caught. Not even druntime does it. For example, if an exception occurs during a static array construction, this triggers the destruction of already constructed items. If one of *those* fails, then the cleanup loop terminates (without cleaning the rest of the items mind you). And the user is greeted with a "Object destruction failed", even though the array was never constructed to begin with! There's merit in the goal, but I don't think the current design has achieved it.On 10/5/2014 10:09 AM, Dicebot wrote:It's one of those designs in which there's little room to turn. We wanted to (a) allow destructors to throw, (b) conserve information. Offering access to all exceptions caught was a natural consequence. -- AndreiOn Sunday, 5 October 2014 at 17:03:07 UTC, Andrei Alexandrescu wrote:FWIW, I'm skeptical as well of the value of chaining relative to its cost in complexity.On 10/5/14, 9:42 AM, Dicebot wrote:Good chunk of issues with pre-allocated exceptions (and possible cycles in reference counted ones) comes from the chanining possibility. At the same time I have yet to see it actively used as a feature. Doesn't mean it is bad thing, just not used wide enough to compensate for trouble right now.On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:What harm does it do? -- AndreiDoes D have exception chaining?Though it seems to do more harm then good so far.
Oct 06 2014
On 10/6/14, 7:24 AM, monarch_dodra wrote:If your "catch" throws an exception, then the new exception simply "squashes" replaces the old one: //---- catch (Exception e) { thisMightThrow(); //Lose "e" here throw e; } //----That's code under library/user control, I'm talking about the responsibility of the language. -- Andrei
Oct 06 2014
On Monday, 6 October 2014 at 14:54:21 UTC, Andrei Alexandrescu wrote:On 10/6/14, 7:24 AM, monarch_dodra wrote:Right. but if correct usage is so cumbersome no one does it right, then it is 's/the responsibility/a flaw/' of the language. Are we advocating then that code under user control should systematically look like this? catch (Exception e) { try { thisMightThrow(); //Lose "e" here } catch(Exception ee) { findLast(e).next = ee; //because e.next might } throw e; } Honestly, a good middle ground is to ditch chaining, but allow multiple exceptions thrown at once. Subsequent Exceptions/Errors will just be lost (sorry), with the exception that an Error will override an Exception. For the sake of argument, do you have any examples where a program has used chaining?If your "catch" throws an exception, then the new exception simply "squashes" replaces the old one: //---- catch (Exception e) { thisMightThrow(); //Lose "e" here throw e; } //----That's code under library/user control, I'm talking about the responsibility of the language. -- Andrei
Oct 06 2014
On 10/6/14, 9:55 AM, monarch_dodra wrote:On Monday, 6 October 2014 at 14:54:21 UTC, Andrei Alexandrescu wrote:Only if it needs to save that information. As far as the core language is concerned, once an exception has been caught and made available to the user, it's up to the user what to do with it. The point of chaining is to not render information inaccessible to user no matter what they do. This is a fairly basic remark.On 10/6/14, 7:24 AM, monarch_dodra wrote:Right. but if correct usage is so cumbersome no one does it right, then it is 's/the responsibility/a flaw/' of the language. Are we advocating then that code under user control should systematically look like this? catch (Exception e) { try { thisMightThrow(); //Lose "e" here } catch(Exception ee) { findLast(e).next = ee; //because e.next might } throw e; }If your "catch" throws an exception, then the new exception simply "squashes" replaces the old one: //---- catch (Exception e) { thisMightThrow(); //Lose "e" here throw e; } //----That's code under library/user control, I'm talking about the responsibility of the language. -- AndreiHonestly, a good middle ground is to ditch chaining, but allow multiple exceptions thrown at once. Subsequent Exceptions/Errors will just be lost (sorry), with the exception that an Error will override an Exception.If I redesigned D's exceptions, I'd change a bunch of stuff before that.For the sake of argument, do you have any examples where a program has used chaining?Whenever an exception is converted to a string, the chained exceptions should be part of it too. Andrei
Oct 06 2014
On Monday, 6 October 2014 at 16:59:35 UTC, Andrei Alexandrescu wrote:Whenever an exception is converted to a string, the chained exceptions should be part of it too.On Monday, 6 October 2014 at 17:12:00 UTC, Jakob Ovrum wrote:However, the whole point is implicit chaining, which is where the language and runtime kicks in. Look through your own scope(exit|failure) blocks and struct destructors - are they all nothrow? If not, you are using exception chaining.Hum... But arguably, that's just exception chaining "happening". Do you have any examples of someone actually "dealing" with all the exceptions in a chain in a catch, or actually using the information in a manner that is more than just printing?
Oct 07 2014
On Tuesday, 7 October 2014 at 07:36:56 UTC, monarch_dodra wrote:"happening". Do you have any examples of someone actually "dealing" with all the exceptions in a chain in a catch, or actually using the information in a manner that is more than just printing?I've never used it myself in real code, but I think the "swallow concurrent exceptions" is very difficult to reason about, because it might be a side effect and not a primary cause. Capturing the origin for a rethrow is potentially useful since it can tell you whether you should retry or not. If the cause is a "network unavailable" then you might want to retry. If the cause is a type error you might want to log an error and bail out.
Oct 07 2014
On 10/7/14, 12:36 AM, monarch_dodra wrote:Hum... But arguably, that's just exception chaining "happening". Do you have any examples of someone actually "dealing" with all the exceptions in a chain in a catch, or actually using the information in a manner that is more than just printing?No. But that doesn't mean anything; all uses of exceptions I know of are used for just printing. -- Andrei
Oct 07 2014
On Tue, 07 Oct 2014 14:39:06 +0100, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 10/7/14, 12:36 AM, monarch_dodra wrote:[not just for printing] 1. I catch a ChangeConflictException and attempt some basic automatic conflict resolution (i.e. column has changed in the database, but I have not changed the local version then merge the value from database) [examining the chain] 2. I catch Exception then test if "ex is TransactionException" AND if "ex.InnerException is TimeoutException" (AKA first in chain) then raise a different sort of alert (for our GUI to display). (FYI the reason I don't have a separate catch block for TransactionException specifically is that it would involve duplicating all the cleanup I am doing in this catch block, all for a 1 line "raise a different alert" call - it just didn't seem worth it) R -- Using Opera's revolutionary email client: http://www.opera.com/mail/Hum... But arguably, that's just exception chaining "happening". Do you have any examples of someone actually "dealing" with all the exceptions in a chain in a catch, or actually using the information in a manner that is more than just printing?No. But that doesn't mean anything; all uses of exceptions I know of are used for just printing. -- Andrei
Oct 08 2014
On Monday, 6 October 2014 at 16:55:39 UTC, monarch_dodra wrote:For the sake of argument, do you have any examples where a program has used chaining?I use explicit chaining in a couple of my libraries, i.e. code like: --- try foo(); catch(FooException e) { throw new BarException("foobar", e); } --- However, the whole point is implicit chaining, which is where the language and runtime kicks in. Look through your own scope(exit|failure) blocks and struct destructors - are they all nothrow? If not, you are using exception chaining.
Oct 06 2014
On Monday, 6 October 2014 at 17:12:00 UTC, Jakob Ovrum wrote:On Monday, 6 October 2014 at 16:55:39 UTC, monarch_dodra wrote:I think this is supposed to chain the other way around.For the sake of argument, do you have any examples where a program has used chaining?I use explicit chaining in a couple of my libraries, i.e. code like: --- try foo(); catch(FooException e) { throw new BarException("foobar", e); } --- However, the whole point is implicit chaining, which is where the language and runtime kicks in. Look through your own scope(exit|failure) blocks and struct destructors - are they all nothrow? If not, you are using exception chaining.
Oct 06 2014
On Monday, 6 October 2014 at 13:48:07 UTC, Andrei Alexandrescu wrote:It's one of those designs in which there's little room to turn. We wanted to (a) allow destructors to throw, (b) conserve information. Offering access to all exceptions caught was a natural consequence. -- AndreiNote that if we reverse the chaining (like java does), then the loop problem mostly disappear. It is still possible to create it, you you got to actively look for it.
Oct 06 2014
On 10/6/14, 7:25 PM, deadalnix wrote:On Monday, 6 October 2014 at 13:48:07 UTC, Andrei Alexandrescu wrote:I knew Python has chaining but not Java. Got a reference handy? My searches suggest that in Java that's a manual technique only. -- AndreiIt's one of those designs in which there's little room to turn. We wanted to (a) allow destructors to throw, (b) conserve information. Offering access to all exceptions caught was a natural consequence. -- AndreiNote that if we reverse the chaining (like java does), then the loop problem mostly disappear. It is still possible to create it, you you got to actively look for it.
Oct 06 2014
On Tuesday, 7 October 2014 at 03:19:06 UTC, Andrei Alexandrescu wrote:Yes there is no language magic to it in java. It is by convention.Note that if we reverse the chaining (like java does), then the loop problem mostly disappear. It is still possible to create it, you you got to actively look for it.I knew Python has chaining but not Java. Got a reference handy? My searches suggest that in Java that's a manual technique only. -- Andrei
Oct 07 2014
On Sunday, 5 October 2014 at 16:42:38 UTC, Dicebot wrote:Though it seems to do more harm then good so far.Hm, so the next field is used for two different purposes? Both for capturing the original exception on a rethrow and for capturing concurrent exceptions originating in a finally block? That is messy. I personally find regular exceptions overcomplicated for a system level language. I think I'd rather allocate resources through manager objects and release on runtime-registered landing pads, allowing the omission of frame-pointers.
Oct 05 2014
On Sunday, 5 October 2014 at 16:30:47 UTC, Ola Fosheim Grøstad wrote:On Sunday, 5 October 2014 at 15:03:08 UTC, ketmar via Digitalmars-d wrote:I know of several cases where this trick was used and it turned out horribly wrong. OOE is NOT recoverable. It may be in some cases, and you can use trick to make them recoverable in more cases, like the one mentioned, but ultimately, you have no guarantee, and worse, no way to know if you are in a recoverable situation or not. The only valid use case i know of to catch this kind of error is at top level to return various error code. Even logging may be broken at this point.so Error should not be catchable and should crash immidiately, without any unwinding. as long as Errors are just another kind of exception, the promise must be kept.I find it strange if you cannot recover from out-of-memory-error. The common trick is to preallocate a bulk of memory, then free it when you throw the out of memory exception so that you can unwind. When destroying the out-of-memory-object you need to reallocate the bulk of memory.
Oct 05 2014
On Monday, 6 October 2014 at 00:29:20 UTC, deadalnix wrote:I know of several cases where this trick was used and it turned out horribly wrong. OOE is NOT recoverable. It may be in some cases, and you can use trick to make them recoverable in more cases, like the one mentioned, but ultimately, you have no guarantee, and worse, no way to know if you are in a recoverable situation or not.You can throw a fatal error if you run out of memory twice. You have to write code that take low memory conditions into account throughout. The problem is not that it is impossible to recover, the problem is that virtual memory have made programmers sloppy.
Oct 05 2014
On Sunday, 5 October 2014 at 15:03:08 UTC, ketmar via Digitalmars-d wrote:On Sun, 05 Oct 2014 14:53:37 +0000 monarch_dodra via Digitalmars-d <digitalmars-d puremagic.com> wrote:Don't put words in my mouth. Also, Errors do only partial stack unwinding, so yes, once an Error has been thrown, your program should terminate.Promises hold provided the precondition your program is in a valid state. Having an Error invalidates that precondition, hence voids that promise.so Error should not be catchable and should crash immidiately, without any unwinding.as long as Errors are just another kind of exception, the promise must be kept.Errors aren't Exceptions. They make no promises.
Oct 05 2014
On Sun, 05 Oct 2014 16:33:48 +0000 monarch_dodra via Digitalmars-d <digitalmars-d puremagic.com> wrote:Errors aren't Exceptions. They make no promises.if it looks like a duck, if it quacks like a duck, if it can be catched like a duck... it's a duck. that's not me who titled exception base class Throwable. it can be catched? it is using 'throw'? it does unwinding? it is an exception. and what means 'partial stack unwinding'? by random, or only even stack frames?
Oct 05 2014
On Sunday, 5 October 2014 at 16:42:24 UTC, ketmar via Digitalmars-d wrote:it does unwinding?It is not guaranteed by spec (I guess this was added to allow assert(0) to be converted into HLT instruction) though in most cases it does. Neither it is guaranteed to run destructors of RAII entities (and it doesn't already for some cases). Pretty much only reason `Error` is not equivalent to plain `abort` call is to allow some last resort debbugging dump and provide more meaningful information about the failure. Any application that tries to recover from Error in any way falls into unstandard D domain.
Oct 05 2014
On Sun, 05 Oct 2014 16:47:26 +0000 Dicebot via Digitalmars-d <digitalmars-d puremagic.com> wrote:Pretty much only reason `Error` is not equivalent to plain=20 `abort` call is to allow some last resort debbugging dump and=20 provide more meaningful information about the failure.than it was done very wrong. it's ok to have some arcane chain of "error handlers" in runtime, 'cause writing such handlers is not the kind of task people do often. but allowing to throw Error as any other exception or to catch Error the same way other exceptions can be catched is misleading. any sane person will think about Error as just another kind of Exception, just with different naming. there must be separate case for Errors, something like "final throw", which will not do ANY unwinding, cannot be catched, and just calling "error handlers chain" and aborts. it's not enough to just paint a duck.
Oct 05 2014
On 2014-10-05 11:28:59 +0000, monarch_dodra said:On Saturday, 4 October 2014 at 18:42:05 UTC, Shammah Chancellor wrote:It doesn't "catch" the error. Propigation should continue as normal. However, in the case I gave a return statement is executed in a cleanup block before propigation can continue. As has been pointed out, this is just like a finally{} block and it behaves the same way. Throws, and returns should be prohibited from those as well.Didn't miss anything. I was responding to Andrei such that he might think it's not so straightforward to evaluate that code. I am with you on this. It was my original complaint months ago that resulted in this being disallowed behavior. Specifically because you could stop error propigation by accident even though you did not intend to prevent their propigation. e.g: int main() { scope(exit) return 0; assert(false, "whoops!"); } -SIsn't this the "should scope(exit/failure) catch Error" issue though? In theory, you should seldom ever catch Errors. I don't understand why "scope(exit)" are catching them.
Oct 05 2014
On Monday, 6 October 2014 at 02:35:52 UTC, Shammah Chancellor wrote:It doesn't "catch" the error. Propigation should continue as normal.Right, it only "intercepts, cleanups, and rethrows". But the argument is that even that shouldn't happen, as you aren't sure the cleanup code is still relevant. At least, I don't think it should be doing cleanup unless you go out of your way to say: "do this, *even* in case of errors". I mean, your RAII has already failed anyways. Your memory has leaked, your ref counts are of the counter, your transactions are open, your file handles are open... The only thing you should be doing is trying to die gracefully, and maybe salvage user data. Your program is in *ERROR*. Cleanup really shouldn't be the priority, especially if it can potentially add more corruption to your state.
Oct 06 2014
On 10/4/14 2:45 PM, Shammah Chancellor wrote:int main() { scope(exit) return 0; assert(false, "whoops!"); }The above smells to me like it should be invalid. Specifically, the scope(exit) line by itself. If you want to catch and not propagate an error, you need to use try/catch directly. scope(exit|success|failure) is for cleaning up resources, not returning from the function. -Steve
Oct 06 2014
On Friday, 3 October 2014 at 17:50:29 UTC, Andrei Alexandrescu wrote:On 10/2/14, 8:23 PM, Ali Çehreli wrote:Unless we have very good reason, the same restrictions as for finally blocks (i.e. the actual lowering) should apply. David"A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto."Seems to me all these restrictions should be lifted. -- Andrei
Oct 03 2014
On 2014-10-03 20:18:44 +0000, David Nadlinger said:On Friday, 3 October 2014 at 17:50:29 UTC, Andrei Alexandrescu wrote:They do.On 10/2/14, 8:23 PM, Ali ehreli wrote:Unless we have very good reason, the same restrictions as for finally blocks (i.e. the actual lowering) should apply. David"A scope(exit) or scope(success) statement may not exit with a throw, goto, break, continue, or return; nor may it be entered with a goto."Seems to me all these restrictions should be lifted. -- Andrei
Oct 03 2014