digitalmars.D.learn - Exception Safe Programming
- Saaa (23/23) Feb 24 2007 On the website there is the following example:
- Jarrett Billingsley (7/28) Feb 24 2007 Nope. If "f = dofoo()" fails and an exception is thrown, that catch blo...
- Saaa (5/10) Feb 24 2007 That is exactly what I originally thought, but why then is that piece of...
- Tyler Knott (52/57) Feb 24 2007 When an exception is thrown and not caught, the compiler unwinds the cal...
- Saaa (3/57) Feb 25 2007 Thanks,
- renoX (5/31) Feb 25 2007 That's probably because this is a counter-example, not an example
- Saaa (4/35) Feb 25 2007 I meant the try statement explanation on
- Frits van Bommel (27/55) Feb 25 2007 The only example I see there is:
- Saaa (7/15) Feb 25 2007 : /
- Frits van Bommel (7/22) Feb 25 2007 Hmm, yes. That section doesn't seem to explain what exceptions *are*,
- Saaa (25/25) Feb 25 2007 Maybe I still don't get it :/
- Tyler Knott (28/59) Feb 25 2007 Somewhere in your program you're trying to open a file called "pictures"...
- Saaa (8/68) Feb 25 2007 Yes the dir is 'pictures', but the program runs perfectly with that last...
- Tyler Knott (5/10) Feb 25 2007 Without seeing more of your program I can't tell what's going on. You'r...
- Saaa (7/17) Feb 25 2007 That is the whole code.. I've stripped it bare. Only a main calling that...
- Tyler Knott (5/14) Feb 25 2007 Ah, I found the problem. You're trying to list the contents of a direct...
- Saaa (4/17) Feb 25 2007 I was that far myself :)
- Daniel Keep (17/36) Feb 25 2007 I've had some *really* bizarre problems with some Exceptions lately. I
- Manfred Nowak (3/5) Feb 25 2007 Not confirmed: DMD 1.007/WinXP32.
- Saaa (4/6) Feb 25 2007 Sorry for wasting everybody's time..
- Saaa (2/2) Feb 25 2007 How do I read the exceptions thrown in the main > scope(failure) ?
- Tyler Knott (8/12) Feb 25 2007 You can't handle any exceptions outside of try-catch-finally blocks. Th...
- Saaa (1/12) Feb 26 2007
On the website there is the following example: Transaction abc() { Foo f; Bar b; f = dofoo(); try { b = dobar(); return Transaction(f, b); } catch (Object o) { dofoo_undo(f); throw o; } } When f=dofoo() is run and doesn't succeed I suspect that f hasn't changed and dofoo has thrown an exception. Because of the exception the try part isn't run, but the catch part is. Did I understand this correctly? The explanation of the try statement on the website is not the most comprehensible one (^.^)
Feb 24 2007
"Saaa" <empty needmail.com> wrote in message news:erqh38$2hen$1 digitalmars.com...On the website there is the following example: Transaction abc() { Foo f; Bar b; f = dofoo(); try { b = dobar(); return Transaction(f, b); } catch (Object o) { dofoo_undo(f); throw o; } } When f=dofoo() is run and doesn't succeed I suspect that f hasn't changed and dofoo has thrown an exception. Because of the exception the try part isn't run, but the catch part is. Did I understand this correctly?Nope. If "f = dofoo()" fails and an exception is thrown, that catch block is not run, because "f = dofoo()" is outside the try block. A catch block is only run if an uncaught exception occurs in the try block right before it. Since "f = dofoo()" is not in a try block, any exception from it will just be thrown out of abc().
Feb 24 2007
That is exactly what I originally thought, but why then is that piece of code a example of how to ... oh wait... if f=dofoo() fails, f is still unchanged and the correct thing to do is to exit the function through an exception. never mind, but thanks :)Nope. If "f = dofoo()" fails and an exception is thrown, that catch block is not run, because "f = dofoo()" is outside the try block. A catch block is only run if an uncaught exception occurs in the try block right before it. Since "f = dofoo()" is not in a try block, any exception from it will just be thrown out of abc().
Feb 24 2007
Saaa wrote:That is exactly what I originally thought, but why then is that piece of code a example of how to ... oh wait... if f=dofoo() fails, f is still unchanged and the correct thing to do is to exit the function through an exception. never mind, but thanks :)When an exception is thrown and not caught, the compiler unwinds the callstack until it finds a handler. What this means is that if a function throws an exception then the program will look for the closest call inside a try block with a following catch block that will accept the type of the exception (or a type the exception is implicitly castable to). So, for example: import std.stdio; class MsgClass { this() { writefln("MsgClass constructed."); } ~this() { writefln("MsgClass destructed."); } } class TestException : Exception { this(char[] msg) { super(msg); } } void thrower() { writefln("Throwing exception."); throw new TestException("This is an exception"); } int inBetween() { //Destructs after the exception because its scope is destroyed by the exception scope MsgClass i = new MsgClass(); thrower(); writefln("Returning 5..."); //Never prints return 5; //Function never returns } void main() { int x; try { x = inBetween(); //x is never assigned } catch(Exception e) { writefln("Caught exception: ", e); } writefln("The value of x is: ", x); //x = 0 } This code will output the following with thrower() called: MsgClass constructed. Throwing exception. MsgClass destructed. Caught exception: This is an exception The value of x is: 0 And this without: MsgClass constructed. Returning 5... MsgClass destructed. The value of x is: 5
Feb 24 2007
Thanks, I understand it now: place 'x = inBetween();' before 'try' and the catch will never run (crash)When an exception is thrown and not caught, the compiler unwinds the callstack until it finds a handler. What this means is that if a function throws an exception then the program will look for the closest call inside a try block with a following catch block that will accept the type of the exception (or a type the exception is implicitly castable to). So, for example: import std.stdio; class MsgClass { this() { writefln("MsgClass constructed."); } ~this() { writefln("MsgClass destructed."); } } class TestException : Exception { this(char[] msg) { super(msg); } } void thrower() { writefln("Throwing exception."); throw new TestException("This is an exception"); } int inBetween() { //Destructs after the exception because its scope is destroyed by the exception scope MsgClass i = new MsgClass(); thrower(); writefln("Returning 5..."); //Never prints return 5; //Function never returns } void main() { int x; try { x = inBetween(); //x is never assigned } catch(Exception e) { writefln("Caught exception: ", e); } writefln("The value of x is: ", x); //x = 0 } This code will output the following with thrower() called: MsgClass constructed. Throwing exception. MsgClass destructed. Caught exception: This is an exception The value of x is: 0 And this without: MsgClass constructed. Returning 5... MsgClass destructed. The value of x is: 5
Feb 25 2007
Saaa a écrit :On the website there is the following example: Transaction abc() { Foo f; Bar b; f = dofoo(); try { b = dobar(); return Transaction(f, b); } catch (Object o) { dofoo_undo(f); throw o; } } When f=dofoo() is run and doesn't succeed I suspect that f hasn't changed and dofoo has thrown an exception. Because of the exception the try part isn't run, but the catch part is. Did I understand this correctly? The explanation of the try statement on the website is not the most comprehensible one (^.^)That's probably because this is a counter-example, not an example really: more a (convincing) way to show that scope() is much better than try/catch for exception safe programming.. renoX
Feb 25 2007
"renoX" <renosky free.fr> wrote in message news:errs2s$1pvc$1 digitalmars.com...Saaa a écrit :I meant the try statement explanation on http://www.digitalmars.com/d/statement.html#TryStatementOn the website there is the following example: Transaction abc() { Foo f; Bar b; f = dofoo(); try { b = dobar(); return Transaction(f, b); } catch (Object o) { dofoo_undo(f); throw o; } } When f=dofoo() is run and doesn't succeed I suspect that f hasn't changed and dofoo has thrown an exception. Because of the exception the try part isn't run, but the catch part is. Did I understand this correctly? The explanation of the try statement on the website is not the most comprehensible one (^.^)That's probably because this is a counter-example, not an example really: more a (convincing) way to show that scope() is much better than try/catch for exception safe programming.. renoX
Feb 25 2007
Saaa wrote:"renoX" <renosky free.fr> wrote in message news:errs2s$1pvc$1 digitalmars.com...[snip]Saaa a écrit :On the website there is the following example: Transaction abc() { Foo f; Bar b; f = dofoo(); try { b = dobar(); return Transaction(f, b); } catch (Object o) { dofoo_undo(f); throw o; } }The only example I see there is: --- int main() { try { try { throw new Exception("first"); } finally { printf("finally\n"); throw new Exception("second"); } } catch(Exception e) { printf("catch %.*s\n", e.msg); } printf("done\n"); return 0; } --- (printf? The horror... :( )That's probably because this is a counter-example, not an example really: more a (convincing) way to show that scope() is much better than try/catch for exception safe programming..I meant the try statement explanation on http://www.digitalmars.com/d/statement.html#TryStatement
Feb 25 2007
: / I meant the explanation itself.... My question was originally about an example from the exception safe programming page. But I just mentioned that the try statement explanation(on http://www.digitalmars.com/d/statement.html#TryStatement ) isn't the most comprehensible.(for me that is:)The only example I see there is: ---That's probably because this is a counter-example, not an example really: more a (convincing) way to show that scope() is much better than try/catch for exception safe programming..I meant the try statement explanation on http://www.digitalmars.com/d/statement.html#TryStatement
Feb 25 2007
Saaa wrote:Ah, I must have read that 'explanation' as 'example'.: / I meant the explanation itself....The only example I see there is: ---That's probably because this is a counter-example, not an example really: more a (convincing) way to show that scope() is much better than try/catch for exception safe programming..I meant the try statement explanation on http://www.digitalmars.com/d/statement.html#TryStatementMy question was originally about an example from the exception safe programming page. But I just mentioned that the try statement explanation(on http://www.digitalmars.com/d/statement.html#TryStatement ) isn't the most comprehensible.(for me that is:)Hmm, yes. That section doesn't seem to explain what exceptions *are*, does it? It seems to assume you already know that. http://www.digitalmars.com/d/errors.html is a bit better, but I'm not sure how clear it is to someone entirely unfamiliar with the concept of exception handling (e.g. someone coming from a purely C background).
Feb 25 2007
Maybe I still don't get it :/ I made this simple function (mostly stolen :) void getPictureList(char[] dir, out char[][] files){ isdir(dir); files = std.file.listdir(dir, "*.png"); foreach (d; files) writefln(d); writefln(files.length); //if(files.length < 12) throw new Exception("Not enough images found(<12)"); } When I uncomment the last line I get: Error: pictures: The system cannot find the file specified. (commented version doesn't generate any errors) There are only 10 files so an exception should be trown, but not that one ! : ) - I call the function in my main and at the end of my main there is: scope(failure) { writefln("Press the 'any' key to quit"); getchar(); } Why isn't this run in the uncommented version? -
Feb 25 2007
Saaa wrote:Maybe I still don't get it :/ I made this simple function (mostly stolen :) void getPictureList(char[] dir, out char[][] files){ isdir(dir); files = std.file.listdir(dir, "*.png"); foreach (d; files) writefln(d); writefln(files.length); //if(files.length < 12) throw new Exception("Not enough images found(<12)"); } When I uncomment the last line I get: Error: pictures: The system cannot find the file specified. (commented version doesn't generate any errors) There are only 10 files so an exception should be trown, but not that one ! : )Somewhere in your program you're trying to open a file called "pictures" which is non-existent (at least where the system is looking) causing an exception.I call the function in my main and at the end of my main there is: scope(failure) { writefln("Press the 'any' key to quit"); getchar(); } Why isn't this run in the uncommented version?Scope guards are excecuted in the reverse order of where they're declared. E.g., using the thrower() function from my last example: void main() { scope(exit) { writefln(); } //newline scope(failure) { writef("scope guards."); //Note: writef (no ln) doesn't add '\n' } scope(failure) { writef("of "); } scope(failure) { writef("an example "); } thrower(); scope failure(failure) { writef("This is "); } } This will print: an example of scope guards.
Feb 25 2007
Saaa wrote:Yes the dir is 'pictures', but the program runs perfectly with that last line commented out. ? I'd expect it to say: Error: Not enough images found(<12)Maybe I still don't get it :/ I made this simple function (mostly stolen :) void getPictureList(char[] dir, out char[][] files){ isdir(dir); files = std.file.listdir(dir, "*.png"); foreach (d; files) writefln(d); writefln(files.length); //if(files.length < 12) throw new Exception("Not enough images found(<12)"); } When I uncomment the last line I get: Error: pictures: The system cannot find the file specified. (commented version doesn't generate any errors) There are only 10 files so an exception should be trown, but not that one ! : )Somewhere in your program you're trying to open a file called "pictures" which is non-existent (at least where the system is looking) causing an exception.:) Thanks again. Somehow I keep thinking of scope failure an a property of the scope. But that analogy only works if the scope failure is actually read. I had it at the end of my main (never read :)I call the function in my main and at the end of my main there is: scope(failure) { writefln("Press the 'any' key to quit"); getchar(); } Why isn't this run in the uncommented version?Scope guards are excecuted in the reverse order of where they're declared. E.g., using the thrower() function from my last example: void main() { scope(exit) { writefln(); } //newline scope(failure) { writef("scope guards."); //Note: writef (no ln) doesn't add '\n' } scope(failure) { writef("of "); } scope(failure) { writef("an example "); } thrower(); scope failure(failure) { writef("This is "); } } This will print: an example of scope guards.
Feb 25 2007
Saaa wrote:Yes the dir is 'pictures', but the program runs perfectly with that last line commented out. ? I'd expect it to say: Error: Not enough images found(<12)Without seeing more of your program I can't tell what's going on. You're right that it should be throwing the "not enough images found" exception, at least based on the snippet you posted. Are you catching the "not enough images found" exception anywhere?
Feb 25 2007
Saaa wrote:That is the whole code.. I've stripped it bare. Only a main calling that function: void main() { char[][] files; getPictureList("pictures",files); }Yes the dir is 'pictures', but the program runs perfectly with that last line commented out. ? I'd expect it to say: Error: Not enough images found(<12)Without seeing more of your program I can't tell what's going on. You're right that it should be throwing the "not enough images found" exception, at least based on the snippet you posted. Are you catching the "not enough images found" exception anywhere?
Feb 25 2007
Saaa wrote:That is the whole code.. I've stripped it bare. Only a main calling that function: void main() { char[][] files; getPictureList("pictures",files); }Ah, I found the problem. You're trying to list the contents of a directory that doesn't exist. The error message isn't very clear, but that's the problem. I don't know why commenting out the line with the throw is changing the behavior of the program, because it shouldn't.
Feb 25 2007
I was that far myself :) It is that I can list everything in that dir when that line is commented out (everything working fine) I too found the error a bit strange, but I thought I shouldn't complain :DSaaa wrote:That is the whole code.. I've stripped it bare. Only a main calling that function: void main() { char[][] files; getPictureList("pictures",files); }Ah, I found the problem. You're trying to list the contents of a directory that doesn't exist. The error message isn't very clear, but that's the problem. I don't know why commenting out the line with the throw is changing the behavior of the program, because it shouldn't.
Feb 25 2007
Saaa wrote:I was that far myself :) It is that I can list everything in that dir when that line is commented out (everything working fine) I too found the error a bit strange, but I thought I shouldn't complain :DI've had some *really* bizarre problems with some Exceptions lately. I made the huge mistake of upgrading the D compiler when I had a working project... spent a week trying to track down a weird bug only to discover that for some reason, D was trying to memset 1.5GB of memory at program startup, and then throwing Win32 exceptions every time I tried to use a string as part of an Exception! Tried to reduce it to a test case, but of course, I couldn't reproduce the problem... *grumble grumble* Sorry, just needed to vent a little. A week staring at assembler and WinDbg only to discover D is doing something strange will do that :P -- Daniel -- Unlike Knuth, I have neither proven or tried the above; it may not even make sense. v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/Saaa wrote:That is the whole code.. I've stripped it bare. Only a main calling that function: void main() { char[][] files; getPictureList("pictures",files); }Ah, I found the problem. You're trying to list the contents of a directory that doesn't exist. The error message isn't very clear, but that's the problem. I don't know why commenting out the line with the throw is changing the behavior of the program, because it shouldn't.
Feb 25 2007
Saaa wroteWhen I uncomment the last line I get: Error: pictures: The system cannot find the file specified.Not confirmed: DMD 1.007/WinXP32. -manfred
Feb 25 2007
Sorry for wasting everybody's time.. Every time I wanted to see what went wrong I ran through commandline and as my pictures get read in relative.... ah well you'll get it :) At least Daniel found this thread useful ; )Not confirmed: DMD 1.007/WinXP32. -manfred
Feb 25 2007
How do I read the exceptions thrown in the main > scope(failure) ? Or should I just put everything in a try-catch ?
Feb 25 2007
Saaa wrote:How do I read the exceptions thrown in the main > scope(failure) ? Or should I just put everything in a try-catch ?You can't handle any exceptions outside of try-catch-finally blocks. The scope guards exist to ensure that any cleanup necessary (such as closing network connections or releasing mutexes in multithreaded programs) gets performed before all references to the associated resources are lost. To actually access the exceptions the exception needs to be thrown in the scope of a try block (somewhere, it doesn't need to be the immediate function) and that try block must have a catch and/or finally block.
Feb 25 2007
Okay, thanks.How do I read the exceptions thrown in the main > scope(failure) ? Or should I just put everything in a try-catch ?You can't handle any exceptions outside of try-catch-finally blocks. The scope guards exist to ensure that any cleanup necessary (such as closing network connections or releasing mutexes in multithreaded programs) gets performed before all references to the associated resources are lost. To actually access the exceptions the exception needs to be thrown in the scope of a try block (somewhere, it doesn't need to be the immediate function) and that try block must have a catch and/or finally block.
Feb 26 2007