|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
I just thought of a question that I have never seen discussed before
(perhaps it is trivial?) and while I think I know the answer I realise that others might have other oppinions, which is why I ask it here. How much code should one put in the try-block, i.e. if you have code such as this: foo; bar; baz; try { somecode; } catch (exception& e) { // ... } and you have to posibility to also put foo, bar, and baz in the try- block, should you do so? I think no, since by limiting the stuff in the try-block I more clearly indicate what might throw (or which depends on something not throwing) than I do if I put as much as possible in it. Are there any other oppinions or motivations? -- Erik Wikström |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Erik Wikström wrote:
> I just thought of a question that I have never seen discussed before > (perhaps it is trivial?) and while I think I know the answer I realise > that others might have other oppinions, which is why I ask it here. > > How much code should one put in the try-block, i.e. if you have code > such as this: > > foo; > bar; > baz; > try { > somecode; > } > catch (exception& e) { > // ... > } > > and you have to posibility to also put foo, bar, and baz in the try- > block, should you do so? > > I think no, since by limiting the stuff in the try-block I more > clearly indicate what might throw (or which depends on something not > throwing) than I do if I put as much as possible in it. Are there any > other oppinions or motivations? > Well that all depends on whether you can recover form an exception in foo and then continue to execute bar and baz. If not, you may as well put the lot in the try block. -- Ian Collins. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On 7 Feb, 10:19, Ian Collins <ian-n...@hotmail.com> wrote:
> Erik Wikström wrote: > > I just thought of a question that I have never seen discussed before > > (perhaps it is trivial?) and while I think I know the answer I realise > > that others might have other oppinions, which is why I ask it here. > > > How much code should one put in the try-block, i.e. if you have code > > such as this: > > > foo; > > bar; > > baz; > > try { > > somecode; > > } > > catch (exception& e) { > > // ... > > } > > > and you have to posibility to also put foo, bar, and baz in the try- > > block, should you do so? > > > I think no, since by limiting the stuff in the try-block I more > > clearly indicate what might throw (or which depends on something not > > throwing) than I do if I put as much as possible in it. Are there any > > other oppinions or motivations? > > Well that all depends on whether you can recover form an exception in > foo and then continue to execute bar and baz. If not, you may as well > put the lot in the try block. In the example I assume that foo, bar, and baz can not throw, only somecode can. So the question could be reformulated as: is there any value in including more code than that which can throw, or that which depends on successful execution of the code that can throw, in the try block? -- Erik Wikström |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
"Erik Wikström" <Erik-wikstrom@telia.com> wrote in news:332f2de4-acb9-
44d9-85af-41e55b846ad3@c23g2000hsa.googlegroups.com: > I just thought of a question that I have never seen discussed before > (perhaps it is trivial?) and while I think I know the answer I realise > that others might have other oppinions, which is why I ask it here. > > How much code should one put in the try-block, i.e. if you have code > such as this: > > foo; > bar; > baz; > try { > somecode; > } > catch (exception& e) { > // ... > } > > and you have to posibility to also put foo, bar, and baz in the try- > block, should you do so? > > I think no, since by limiting the stuff in the try-block I more > clearly indicate what might throw (or which depends on something not > throwing) than I do if I put as much as possible in it. Are there any > other oppinions or motivations? > > -- > Erik Wikström There are, of course, several of issues to consider. Since anything declared in the try block is unavailable in the catch block, you automatically end up with stuff that is at least declared outside the try/catch construct. I mean, if nothing else, you often want to log something in the catch block. However, balancing that is the desire to keep things that logically belong together in the same scope so that it is obvious that they belong together. So, I guess the points I have made so far are that you likely to have things outside the try block anyway, therefore aesthetics doesn't really play into the picture. On the other hand, code grouping might. From a practical point of view, the point of a try catch is a form of flow of control so that you can automatically skip some code if a predecessor throws. In that case, you will want the code to be skipped in your try block. In your example, if bar can throw and baz relies on the results of bar, then you will definitely want both bar and baz in the try block. This plays more into my own personal view which is that try/catch is a flow of control statement (though somewhat of a syntactical heavyweight) and much like an if stmt, you only put the code in the try block which is useful to be there. Now, I will also say that I find the try/catch syntax heavy weight enough that I try to have at most one in a function. This, for me, addresses the code grouping point above. Just my opinion. joe |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Feb 7, 10:05 am, "Erik Wikström" <Erik-wikst...@telia.com> wrote:
> I just thought of a question that I have never seen discussed before > (perhaps it is trivial?) and while I think I know the answer I realise > that others might have other oppinions, which is why I ask it here. > How much code should one put in the try-block, i.e. if you have code > such as this: > foo; > bar; > baz; > try { > somecode; > } > catch (exception& e) { > // ... > } > and you have to posibility to also put foo, bar, and baz in the try- > block, should you do so? > I think no, since by limiting the stuff in the try-block I > more clearly indicate what might throw (or which depends on > something not throwing) than I do if I put as much as possible > in it. Are there any other oppinions or motivations? Two guiding principles, IMNO: -- I like to keep the try blocks as small as possible, in order to keep the error handling code as near to the source of the error as possible. -- If a variable will not meet the required invariants in the catch clause, or after, its definition belongs in the try block. In general, however, it's best to avoid try blocks completely, and use destructors. Even to the point of defining a special transaction type to handle it. And while I've not experimented with it, I suspect that something along the lines of Andrei's scope guard could be used to great avail here. It should be possible to modify it to something along the lines of: foo ; ON_ERROR( foo cleanup ; ) bar ; ON_ERROR( bar cleanup ; ) // ... -- James Kanze (GABI Software) email:james.kanze@gmail.com Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On 2008-02-08 03:50:51 -0500, James Kanze <james.kanze@gmail.com> said:
> [...] > Two guiding principles, IMNO: > > -- I like to keep the try blocks as small as possible, in order > to keep the error handling code as near to the source of the > error as possible. Interesting. I would think exception handling codes are about the exceptions to the normal flow of logic. Hence I would move it out of the code logic. In another word, try to keep the try blocks as large as possible. Further, keep the try blocks as small as possible would likely cost a run-speed penalty for setting up the try-blocks so often. Of course, if an exception is expected to happen a lot, then perhaps it shouldn't be implemented as a C++ exception to begin with. If that is the case, make explicit codes in the normal logic to handle these cases. These are just my humble opinions. > > -- If a variable will not meet the required invariants in the > catch clause, or after, its definition belongs in the try > block. Can you clarify a bit what you mean by "invariants in the catch clause?" > > In general, however, it's best to avoid try blocks completely, > and use destructors. Even to the point of defining a special > transaction type to handle it. And while I've not experimented > with it, I suspect that something along the lines of Andrei's > scope guard could be used to great avail here. It should be > possible to modify it to something along the lines of: > > foo ; > ON_ERROR( foo cleanup ; ) > bar ; > ON_ERROR( bar cleanup ; ) > // ... -- // kira |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On 2008-02-08 07:15:23, Kira Yamato wrote:
> On 2008-02-08 03:50:51 -0500, James Kanze <james.kanze@gmail.com> said: > >> -- I like to keep the try blocks as small as possible, in order >> to keep the error handling code as near to the source of the >> error as possible. > > Interesting. I would think exception handling codes are about the > exceptions to the normal flow of logic. Hence I would move it out of > the code logic. In another word, try to keep the try blocks as large > as possible. I guess that depends on other criteria, too. Say you have a library that throws on certain conditions. You know you can and want to handle this condition locally. But the calls in the whole code snippet in question may throw all kinds of other stuff that's mostly fatal. So I'd create a try/catch block around that library call, catching the condition I can and want handle locally, and anything else I just let throw its way up the call chain. This would be an example where it makes sense to keep the try block as small as possible. Gerhard |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On 2008-02-08 10:15, Kira Yamato wrote:
> On 2008-02-08 03:50:51 -0500, James Kanze <james.kanze@gmail.com> said: > >> -- If a variable will not meet the required invariants in the >> catch clause, or after, its definition belongs in the try >> block. > > Can you clarify a bit what you mean by "invariants in the catch clause?" Consider something like this: class Bar; //... Bar b; try { // modify b } catch(exception& e) { // Can I be sure that b is in a "good" state here? } If I can not be sure it will be in a known, good and usable state (its invariants are preserved) in the catch-block then the declaration of b should be in the try-clock as well. -- Erik Wikström |
|
![]() |
| Outils de la discussion | |
|
|