
This is the typical use, that of exceptional cases. Luckily, what is exceptional at one level can be totally tolerable at a higher (and invoking and/or embedding...) level, thus we can use a try-catch construct and throw an exception.
Ok, you wrote just before that :
I will send back an equivalent snippet without such breaks, indicating what performance penalties one might have in cleansing the code from breaks.
So I suppose we are ok to forget the performances impact, if I look at your 'exception-based' system :-). As I said performance of the proposed 'Breakable struct' are not perfect, but I believe it to be much better than your exception-based solution. Anyway, considering exception, it is a good way to do it, but : 1/ exception are not available on every platform 2/ If I want to throw an exception to an outside function (ex:bad_alloc), instead of breaking inside the 'breakable structure' this can make things less manageable (obliged carefully select exception types, or even rethrow if needed etc...). 3/ I find the 'breakable structure' still much more readable than the exception one. When you use Exception, you are forced to 'catch' correctly. This can go out of scope easily if you make a mistake. And if you make a mistake in the kind of exception you throw, the compiler won't tell you. When you got only 1 macro to write, sincerily, how could you make a mistake? This is about writing code that won't allow to do more error. Code cleanness and readability. A last element about exception and how not to abuse them : " There are two basic questions you should ask yourself when deciding whether to throw an exception in response to some event. The first is (1) "should this event occur in the normal use of my library component?" The second question is (2) "if this event were to occur, is it likely that the user will want to place the code for dealing with the event near the invocations of my library component?" If your answers to the above two questions are "no" then you should probably throw an exception in response to the event. On the other hand, if you answer "yes" to either of these questions then you should probably not throw an exception. "source :http://dclib.sourceforge.net/howto_contribute.html#8 With this kind of thinking, it also seems clear that exception are overkill in the case of most uses of a 'breakable structure'. Best regards, Pierre --- En date de : Dim 6.9.09, David Bergman <David.Bergman@bergmangupta.com> a écrit : De: David Bergman <David.Bergman@bergmangupta.com> Objet: Re: [boost] [Boost.Breakable] Any interest in a Boost Breakable library? À: boost@lists.boost.org Date: Dimanche 6 Septembre 2009, 14h29 On Sep 6, 2009, at 5:09 PM, Pierre Morcello wrote:
What is a "break-scope problem" to you? I think you might use the wrong "analysis pattern" here...
I was reusing the same kind of words than the previous comment of Stefan Strasser, to answer clearly to his remarks. Sorry if it made things less clear: He wrote "if you need a construct that forms a scope, accomplishes a tasks and then exists the scope from anywhere in between, that's a function.". He was presenting things like a problem and its solution.
I have never heard of 'analysis pattern', only 'design patterns' and 'idioms'. I will look at this.
Anyway just let compare 2 sample codes:
Of course people can already write : if(!filestream.bad()) { if(!filestream.good()) { if(xmlLoadFrom(filestream)) { // and so on, to test if the xml is valid, etc... }else{ log("the file is no xml document."); } }else{ log("error inside the file (eof)"); } }else{ log("error at opening file"); }
and :
Breakable { if(!filestream.bad()) { log("error at opening file"); break; }
if(!filestream.good()) { log("error inside the file (eof)"); break; }
if(!xmlLoadFrom(filestream)) { log("the file is no xml document."); break; }
// and so on, to test if the xml is valid, etc... }
Have a deep breath, compare, and then tell me which is more readable. Which is the easier to maintain? If another test is to be added, which version will be the simpliest to modify?
For these 3 reasons, I prefer the second one.
If you think this usage might lead to problems, could you explain which ones ?
This is the typical use, that of exceptional cases. Luckily, what is exceptional at one level can be totally tolerable at a higher (and invoking and/or embedding...) level, thus we can use a try-catch construct and throw an exception. I am not a friend of emulating local exception handling by breaks. So, in this case (and even meta case) I would use try { if (filestream.bad()) throw boost::exception("error at opening file"); if (!filestream.good()) throw boost::exception("error inside the file (eof)"); // Main logic xmlLoadFrom(filestream); // assuming that 'xmlLoadFrom' uses exceptions properly as well... } catch (const boost::exception& ex) { log(ex.what()); }
Best regards,
Pierre
PS: if you know a good source about "analysis pattern", don't hesitate to tell me. Right now, I will check the wikipedia page.
I just coined that term - at least AFAIK. What I meant by it? Well, similar to design pattern but applied in the analysis of problems, as a Minsky frame, perhaps. /David _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost