A Programming Question
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
Nope. I'll exit when I damn well please. ;) Kyosa Jamie Nordmeyer - Taekwondo Yi (2nd) Dan Portland, Oregon, USA
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
I do try and aim on having a single exit point for methods, but with C++ it isn't quite as important IMHO (thanks to destructors and smart pointers, etc.) - and it can lead to some very deep nesting, which might not necessarily be that readable. Most people I've spoken to in the office agree that it is preferable to have a single exit point, especially when maintaining other peoples code. As for loops - I use break often. Shrug.
The Rob Blog
Google Talk: robert.caldecott -
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
It depends. Sometimes having just one exit point makes it easier to read. Sometimes it doesn't. I just try and write code that is easy to read and maintain. So, I don't have a hard and fast rule.
My: Blog | Photos "Man who stand on hill with mouth open will wait long time for roast duck to drop in." -- Confucious
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
I tend to try to keep local variables to a minimum so that multiple exit points don't cause a problem. I find they make code cleaner and easier to read as long as you don't have to change a lot of state in order to exit. Having to do that just tells me that the method is trying to do too much and needs to be simplified. I rarely have methods with blocks nested more then 1 or 2 deep, and never have nested try catch blocks.
-
Drew Stainton wrote:
I start by assigning a default return value to a local variable and then use that variable as part of the conditional in whatever loops I'm using - nested or otherwise.
I use this approach as well, except when you using
foreach
because, of course, there's no place to test the conditional as there is in afor
orwhile
loop. Of course, one could use an enumerator in awhile
loop instead:bool found = false;
IEnumerator en = someCollection.GetEnumerator();while(!found && en.MoveNext())
{
if(en.Current == soughtAfterValue)
{
// Take some action.
found = true;
}
}return found;
However, I usually take this approach:
bool found = false;
foreach(SomeObject obj in someCollection)
{
if(obj == soughtAfterValue)
{
// Take some action.
found = true;
break;
}
}return found;
I think either way is fine, but I think the second approach is a little clearer. So I don't think breaks within loops are automatically bad. I do like to avoid more than one return within a method, however. I break this rule from time to time if I think it will make the algorithm clearer, but I like having one return at the bottom of the method.
Leslie Sanford wrote:
So I don't think breaks within loops are automatically bad
I totally agree - didn't mean to imply they were bad. I don't like using them but that's just my choice. You're right about foreach. To be honest I don't use it if the loop has early termination conditions. In those cases I use an enumerator. I really like knowing up front all of the conditions the loop is dependent on. Cheers, Drew.
-
Nishant Sivakumar wrote:
*ahem*
You realize you're the first one to catch that. :-D Good call! I may harrass people about spelling errors, but those are nothing compared to a bad programming example error! Marc VS2005 Tips & Tricks -- contributions welcome!
he omitted this line:
#define void MyRet;
:rolleyes: ;) Steve -
he omitted this line:
#define void MyRet;
:rolleyes: ;) SteveYou're Satan, aren't you? :) ¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF!
-
Leslie Sanford wrote:
So I don't think breaks within loops are automatically bad
I totally agree - didn't mean to imply they were bad. I don't like using them but that's just my choice. You're right about foreach. To be honest I don't use it if the loop has early termination conditions. In those cases I use an enumerator. I really like knowing up front all of the conditions the loop is dependent on. Cheers, Drew.
About breaking out of
foreach
...Drew Stainton wrote:
To be honest I don't use it if the loop has early termination conditions. In those cases I use an enumerator. I really like knowing up front all of the conditions the loop is dependent on.
You know, this is a good point. I will consider it next time I'm thinking about using
foreach
in that way. -
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
Was this a trick question?? How can you have
return ret;
in a function of typevoid
??? :wtf: :wtf: But just in case if this was a typo ... Return immidiately ... - if in a simple "If" and single "Else" block.If (condition) return x; else return false;
- or if in a simple switch statement If I'm implementing a complex logic in my method, then I have a single point of exit. But then again, there is no one right way. My decision making also depends on my mood :) . - Malhar -
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
Personally I use
goto
's for difficult flow control, screw style! Just get it working the best it can be! [update] counted 6 goto's in the C# part of xacc :). Here's a nice example://some code before
foreach (MRUFile mru in recentfiles)
{
if (mru.filename == filename)
{
mru.Update();
goto DONE;
}
}
recentfiles.Add( new MRUFile(filename));DONE:
//some code afterNow I can already hear the cursing, but any other form of flow control, you need 1 or more variables to carry some (unneeded, and extra) state, and make the whole thing much less readable. :-D [update] xacc.ide-0.1-rc4 released! Download and screenshots -- modified at 16:19 Monday 14th November, 2005
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
I prescrive to that for small functions. For larger ones with multiple nested loops, I would probably just got for return statment, and highlight it with decent comments and spacing. That, or go for the dreaded goto :-D
"Je pense, donc je mange." - Rene Descartes 1689 - Just before his mother put his tea on the table. Shameless Plug - Distributed Database Transactions in .NET using COM+
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
I have a bail-out return statement at the beginning of a function if there are immediate problems (bad input, object not setup etc), and I'll often do the same with loops (use a
continue
if it's immediately apparant that the loop should skip this particular iteration. And sometimes I throw in a random return path in the middle of a function because I'm evil. cheers, Chris MaunderCodeProject.com : C++ MVP
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
...sorta. Non-trivial methods generally start by checking the validity of any parameters, the state of the class, etc. If any of these "sanity checks" fail, i immediately return an error. After that, i try and keep all returns at the end of the method, regardless of where the value originates. I have no qualms about using
break
orcontinue
in loops though - if a loop gets to where such things would make the code hard to follow, chances are it's a good time to refactor it anyway.You must be careful in the forest Broken glass and rusty nails If you're to bring back something for us I have bullets for sale...
-
Personally I use
goto
's for difficult flow control, screw style! Just get it working the best it can be! [update] counted 6 goto's in the C# part of xacc :). Here's a nice example://some code before
foreach (MRUFile mru in recentfiles)
{
if (mru.filename == filename)
{
mru.Update();
goto DONE;
}
}
recentfiles.Add( new MRUFile(filename));DONE:
//some code afterNow I can already hear the cursing, but any other form of flow control, you need 1 or more variables to carry some (unneeded, and extra) state, and make the whole thing much less readable. :-D [update] xacc.ide-0.1-rc4 released! Download and screenshots -- modified at 16:19 Monday 14th November, 2005
Maybe I should put
g*to
in the Bad Words filter list. cheers, Chris MaunderCodeProject.com : C++ MVP
-
Really :omg: Not even:
Something* SearchForSomething(...) { Something* pSomethingTested; Something* pSomethingFound = NULL; while( !pSomethingFound ){ pSomethingTested = GetPointertoWhatever(); if( pSomethingTest matches my search criteria ){ pSomethingFound = pSomethingTested; } } return pSomethingFound; }
It really IS that simple and straightforward :->Actually, in strictest terms, your test
whiel( !pSomethingfound )
violates "decent" coding standards. Only booleans should be tested in this manner. A pointer should be explicitly tested against 0 (or NULL, if defined). Just my itty 2 cents ;) Bob Ciora -
...sorta. Non-trivial methods generally start by checking the validity of any parameters, the state of the class, etc. If any of these "sanity checks" fail, i immediately return an error. After that, i try and keep all returns at the end of the method, regardless of where the value originates. I have no qualms about using
break
orcontinue
in loops though - if a loop gets to where such things would make the code hard to follow, chances are it's a good time to refactor it anyway.You must be careful in the forest Broken glass and rusty nails If you're to bring back something for us I have bullets for sale...
I do the same thing. Also, continues help reduce nesting in loops, making the code more readable. I validate input at the top of loops and continue out if invalid, just like how I validate arguments at the top of a function and return out if invalid.
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
I try to follow this ideal, but I won't write convoluted code to make it happen, for example, I wouldn't write something that sets i and j to values that will break the outer loops. Christian Graus - Microsoft MVP - C++
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
Marc Clifton wrote:
There's a philosophy about always having one exit point in a method
Yes, that's exactly what it is, a "philosophy". And your last paragraph explains very well why it is an outdated one. The whole thing started back in the days when programming meant either Fortran or assembler. And the people that frown upon multiple return points don't like break statements in loops either, they say they are just fake go-to statements. I think code clarity is always a lot more important than any other philosophy. Try this test: add another 20 lines to your function, 2 more preconditions (oyOyOy and oops :-) ) and at least one try-catch and then write the code both ways: with preconditions and with early return. Then get one of your coleagues to have a look at your code and try to understand it. See which version was best. If you need an "excuse", look at it as "programming by contract": if the preconditions are not met, you don't even start processing. OGR
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
Please wait while I consult with my Rice Krispies. :~ Where's the milk...? :-D RageInTheMachine9532 "...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
-
Really, this is a programming question. There's a philosophy about always having one exit point in a method, so, you'll typically see something like this: void Foo() { MyRet ret=null; if (blah) { ret=bar; } return ret; } Or, if it's a for loop, ret will be assigned followed by a break. First off, do you prescribe to that philosophy? Do you do so religiously? If so, what do you do when you have several nested loops, and you need to break out of the innermost one and return the value? :) Marc VS2005 Tips & Tricks -- contributions welcome!
Style and phylosophy be damned. The most important things in programming is to be correct, consise and clear. The whole notion of having one exit point in a function was an axiom of good ASSEMBLY and MACHINE language programming. Which "some" people insist on following in higher level languages. The fact is, all functions in higher level languages really do only have one exit point (did you know you can put a breakpoint on the closing brace '}' of a function? try it, you'll like it - and it proves my point). So having multiple return statements is not a problem. Neither is using continue, goto or break. It all depends on the situation.