goto [modified]
-
I don't use it because I understood why it was regarded as bad, and I've never been in a situation where goto would have made my code better. The closest I would get is to regard goto as another way to handle code that is at least as well handled by try/catch. Not sure what you mean by 'making private methods for the sake of avoiding goto', if you have code that needs to be pointed to only sometimes, refactoring it to a new method just makes sense.
Christian Graus - Microsoft MVP - C++ "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
Christian Graus wrote:
The closest I would get is to regard goto as another way to handle code that is at least as well handled by try/catch.
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dllxacc.ide
IronScheme a R5RS-compliant Scheme on the DLR
The rule of three: "The first time you notice something that might repeat, don't generalize it. The second time the situation occurs, develop in a similar fashion -- possibly even copy/paste -- but don't generalize yet. On the third time, look to generalize the approach." -
Rama Krishna Vavilala wrote:
I never had any reason to use it [goto]. If you keep function small and use exception handling you don't need to use goto.
But are exceptions any better that goto's? Joel Spolsky might say no. In fact, in one of his articles, Joel writes that:
...I consider exceptions to be no better than "goto's", considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto's: 1. They are invisible in the source code... there is no way to see which exceptions might be thrown and from where.[...] 2. They create too many possible exit points for a function. To write correct code, you really have to think about every possible code path through your function.
Now, I won't go out there as far as he did and say that exceptions are worse that goto's. But I don't see exceptions as being significantly better. A goto is to your control flow as a pointer is to your data. Both can be significantly misused. However, it is appropriate to use them at times. Joel's second problem with exceptions is too many possible exit points. I believe there should be a single exit from a function. I would rather use
goto exit_;
// many lines snipped
exit_:
return foo;than have multiple returns in a function. It's too difficult when you have multiple returns and you need to modify the behavior to add a bit of logic at the end. At least, that's my opinion.
Tony Wesley wrote:
It's too difficult when you have multiple returns
This was true during times of Fortran, C, and Assembly when global data aND jumps. With languages such as Java and C# shorter functions make this a little conservative. I still follow the (1 exit) rule while writing C++ code but no longer follow it for writing C# as I don't exceed more than 25 lines of code in a function. Either way the aim is to write easy to understand code rather than follow the rules because it comes from Joel Spolsky or Kent beck or Martin Fowler.
Co-Author ASP.NET AJAX in Action CP Quote of the Day: It is the same Friday that blooms as a new enriching day with novelty and innovation for us every week. - Vasudevan Deepak Kumar
-
Okay, so this isn't 100% a lounge question, but I'm asking this to stir controversy for the sake of entertainment, so I'll post here. Is goto really that bad? I'm beginning to wonder if it's just peer pressure and scariness that's making people avoid it. There are undeniably occasions in which goto enables the most readable code. Making private methods just for the sake of avoiding goto seems more spaghetti to me, as does using more local booleans and if/elses for flagging. If I were a teacher, I might not teach students to use goto, because they'll likely abuse it. But if I was evaluating a student's code and they use goto appropriately, I'd probably give them bonus marks for being bold. So, is it only because you've been taught not to use goto that you don't use it? -- modified at 22:22 Friday 23rd November, 2007 Or... http://xkcd.com/292/[^] By the way, let me restate the question: I know goto isn't necessary, but are there cases in which it's more appropriate?
reinux wrote:
Is goto really that bad?
I don't think so. I started off in high school writing spaghetti basic with GOTOs all over the place. I didn't know any better and I'm not such many did at the time. Certainly Edsger Dijkstra did, with his 1968 letter Go To Statement Considered Harmful but no one back at Warren High School in 1971 had that notion. Along the way, I learned to write Structure Programming while taking Algol. I recall discovering that I could use GOTO in Algol and used it in a program. Dr. David E. Boddy wrote on my program in large red letters "No! NO! NO!!!". And he was right. I used it when it was unnecessary, mostly as a way out of a bad design. But there are times to use it. I recently posted a snippet of my own code with goto's over in Coding Horrors (this code wasn't the coding horror :laugh: although some may disagree)
if (keyword (TokenSubtype::Group)) { if (!group\_label (groupName)) { errorMessage = myName + ": Missing GROUP label\\n" + errorMessage; errorCode = DL\_ERROR; goto exit\_; } if (!separator (TokenSubtype::Colon)) { errorMessage = myName + ": Missing colon following GROUP label"; errorCode = DL\_ERROR; goto exit\_; }
// etc...
A goto is to your control flow as a pointer is to your data. Use carefully and with discipline. And remember if you use one: even if you're right, it's like using a split infinitive; some people are going to think you're wrong.
-
Okay, so this isn't 100% a lounge question, but I'm asking this to stir controversy for the sake of entertainment, so I'll post here. Is goto really that bad? I'm beginning to wonder if it's just peer pressure and scariness that's making people avoid it. There are undeniably occasions in which goto enables the most readable code. Making private methods just for the sake of avoiding goto seems more spaghetti to me, as does using more local booleans and if/elses for flagging. If I were a teacher, I might not teach students to use goto, because they'll likely abuse it. But if I was evaluating a student's code and they use goto appropriately, I'd probably give them bonus marks for being bold. So, is it only because you've been taught not to use goto that you don't use it? -- modified at 22:22 Friday 23rd November, 2007 Or... http://xkcd.com/292/[^] By the way, let me restate the question: I know goto isn't necessary, but are there cases in which it's more appropriate?
For languages without exception handling (c) the goto is pretty handy for error handling. Just a cheap try / catch. You might even find a setjmp longjmp call useful on occasion for deeply nested errors.
-
Tony Wesley wrote:
It's too difficult when you have multiple returns
This was true during times of Fortran, C, and Assembly when global data aND jumps. With languages such as Java and C# shorter functions make this a little conservative. I still follow the (1 exit) rule while writing C++ code but no longer follow it for writing C# as I don't exceed more than 25 lines of code in a function. Either way the aim is to write easy to understand code rather than follow the rules because it comes from Joel Spolsky or Kent beck or Martin Fowler.
Co-Author ASP.NET AJAX in Action CP Quote of the Day: It is the same Friday that blooms as a new enriching day with novelty and innovation for us every week. - Vasudevan Deepak Kumar
Rama Krishna Vavilala wrote:
This was true during times of Fortran, C, and Assembly
It's still that time I think. There are more than a few people using these languages. :)
-
for(i = 0; i < array.Length; i++)
{
if(array[i] == 5)
{
Cosole.WriteLine("5 at " + i);
return;
}
}
Cosole.WriteLine("5 not found");I am not a fan of 1 exit per function rule anymore as it has become outdated as functions IMHO should not be more than 25 lines. I refactor any functions which go more than 25 lines. or better yet
int i = array.Find(5);
if (i == -1)
Console.WriteLine("Not found");
else
Console.WriteLine("Found");Co-Author ASP.NET AJAX in Action CP Quote of the Day: It is the same Friday that blooms as a new enriching day with novelty and innovation for us every week. - Vasudevan Deepak Kumar
I'm not too gung-ho about the one exit rule either, but I don't like making more methods when they only get called once. You end up having to change the arguments and parameters in two locations of code every time you decide that you want to use another local. I also don't like putting processing code in the middle of search code because it gets hard to follow execution flow (I like being able to read code in a general top-to-bottom order), and because I don't want to refractor just to fix that, for the reason I mention above.
-
Tony Wesley wrote:
It's too difficult when you have multiple returns
This was true during times of Fortran, C, and Assembly when global data aND jumps. With languages such as Java and C# shorter functions make this a little conservative. I still follow the (1 exit) rule while writing C++ code but no longer follow it for writing C# as I don't exceed more than 25 lines of code in a function. Either way the aim is to write easy to understand code rather than follow the rules because it comes from Joel Spolsky or Kent beck or Martin Fowler.
Co-Author ASP.NET AJAX in Action CP Quote of the Day: It is the same Friday that blooms as a new enriching day with novelty and innovation for us every week. - Vasudevan Deepak Kumar
Rama Krishna Vavilala wrote:
Either way the aim is to write easy to understand code rather than follow the rules because it comes from Joel Spolsky or Kent beck or Martin Fowler.
I'm in complete agreement with you!
-
I am talking about those situations where goto is used for error handling and clean up. In fact that is the most common use I have seen in c++ code aka MFC and ATL.
void FunctionWithGoTo()
{
if (!(OpenFile()) GoTo Cleanup;if (!FileFormatIsValid()) GoTo CleanUp;
if (!RecordExists()) GoTo CleanUp;
....
CleanUp://Do some clean up work like closing the file
}You can rewrite it
void FunctionWithGoTo()
{
try
{
OpenFile();
ValidateFileFormat();
ValidateRecordExists();
.... other stuff
}
catch(//appropriate exceptions)
{}
finally
{
///Cleanup
}}
If you use RAII you can simplify the code further. So I guess it is difficult to come up with situations in modern languages like C++, C# Java etc. to use GoTo.
Co-Author ASP.NET AJAX in Action CP Quote of the Day: It is the same Friday that blooms as a new enriching day with novelty and innovation for us every week. - Vasudevan Deepak Kumar
In your examples, I prefer the version with the gotos. I can't tell which of OpenFile() or ValidateFileFormat() or ValidateRecordExists() might throw an exception.
-
Win32 APIs are meant for C.
Hope is the negation of reality - Raistlin Majere
They're still often the only option even from C++ or VB or any other language. Or C# for that matter, though luckily P/Invoke wraps those return values in exceptions.
-
Okay, so this isn't 100% a lounge question, but I'm asking this to stir controversy for the sake of entertainment, so I'll post here. Is goto really that bad? I'm beginning to wonder if it's just peer pressure and scariness that's making people avoid it. There are undeniably occasions in which goto enables the most readable code. Making private methods just for the sake of avoiding goto seems more spaghetti to me, as does using more local booleans and if/elses for flagging. If I were a teacher, I might not teach students to use goto, because they'll likely abuse it. But if I was evaluating a student's code and they use goto appropriately, I'd probably give them bonus marks for being bold. So, is it only because you've been taught not to use goto that you don't use it? -- modified at 22:22 Friday 23rd November, 2007 Or... http://xkcd.com/292/[^] By the way, let me restate the question: I know goto isn't necessary, but are there cases in which it's more appropriate?
I've only used goto once, it was to add a resume function. It struck me as simpler to impliment then to re factor the function into several smaller functions.
-
They're still often the only option even from C++ or VB or any other language. Or C# for that matter, though luckily P/Invoke wraps those return values in exceptions.
Yep, but Rama's point was that "it is difficult to come up with situations in modern languages like C++, C# Java etc. to use GoTo." What I meant is that since Win32 API was written for C, if you want to use them you'll have to do it the C way, and perhaps mix it with C++ exceptions, such as:
HANDLE h = FindFirstFile(_T("AVeryImportantFile.txt"), &WIN32_FIND_DATA());
if (h == INVALID_HANDLE_VALUE)
throw CException(_T("A very important file is missing."));
Hope is the negation of reality - Raistlin Majere
-
reinux wrote:
Something about that extra bool and if/else really bugs me.
Me too. I think your example doesn't make much difference, one way or another. But if the loops are nested, you have to have break out of multiple levels.
Oops, I knew that. Yeah. Uh huh. Yup. Totally knew that. Yup. Yup... :~
-
Okay, so this isn't 100% a lounge question, but I'm asking this to stir controversy for the sake of entertainment, so I'll post here. Is goto really that bad? I'm beginning to wonder if it's just peer pressure and scariness that's making people avoid it. There are undeniably occasions in which goto enables the most readable code. Making private methods just for the sake of avoiding goto seems more spaghetti to me, as does using more local booleans and if/elses for flagging. If I were a teacher, I might not teach students to use goto, because they'll likely abuse it. But if I was evaluating a student's code and they use goto appropriately, I'd probably give them bonus marks for being bold. So, is it only because you've been taught not to use goto that you don't use it? -- modified at 22:22 Friday 23rd November, 2007 Or... http://xkcd.com/292/[^] By the way, let me restate the question: I know goto isn't necessary, but are there cases in which it's more appropriate?
reinux wrote:
So, is it only because you've been taught not to use goto that you don't use it?
No, it's because i don't need it. In fact, i was reminded by a co-worker just last week of the last instance where i used goto. Seems i had to fix a bug in a monstrous piece of legacy code, a method many hundreds of lines long with plenty of twisted internal control structures and cleanup needs. After spending the better part of an evening figuring out how the thing worked, i fixed the problem and threw in a goto as part of the cleanup, commenting that it couldn't really make the damn thing any worse. The routine was divided up and re-written during the past month. Needless to say, my goto is no longer a part of it. ;)
reinux wrote:
Making private methods just for the sake of avoiding goto seems more spaghetti to me, as does using more local booleans and if/elses for flagging.
Actually, i'd argue that a sufficient quantity of properly-chosen (and named...) private methods not only makes the code more readable, but also effectively eliminates most scenarios where internal booleans, long conditionals, or gotos might otherwise be used. And that's a good thing. ;)
----
...the wind blows over it and it is gone, and its place remembers it no more...
-
Yep, but Rama's point was that "it is difficult to come up with situations in modern languages like C++, C# Java etc. to use GoTo." What I meant is that since Win32 API was written for C, if you want to use them you'll have to do it the C way, and perhaps mix it with C++ exceptions, such as:
HANDLE h = FindFirstFile(_T("AVeryImportantFile.txt"), &WIN32_FIND_DATA());
if (h == INVALID_HANDLE_VALUE)
throw CException(_T("A very important file is missing."));
Hope is the negation of reality - Raistlin Majere
Well if we were discussing the pure theory behind the languages, yeah, goto is less useful in C++. But in practice C calls inevitably become necessary, unless you're using BeOS or something, which has a purely C++ API. And yeah, in this case you could use an exception instead of a goto. But if you're planning to catch the exception within the same caller function, you might as well use a goto, no? My question isn't so much whether goto is necessary, but whether there are cases in which it's more appropriate.
-
reinux wrote:
So, is it only because you've been taught not to use goto that you don't use it?
No, it's because i don't need it. In fact, i was reminded by a co-worker just last week of the last instance where i used goto. Seems i had to fix a bug in a monstrous piece of legacy code, a method many hundreds of lines long with plenty of twisted internal control structures and cleanup needs. After spending the better part of an evening figuring out how the thing worked, i fixed the problem and threw in a goto as part of the cleanup, commenting that it couldn't really make the damn thing any worse. The routine was divided up and re-written during the past month. Needless to say, my goto is no longer a part of it. ;)
reinux wrote:
Making private methods just for the sake of avoiding goto seems more spaghetti to me, as does using more local booleans and if/elses for flagging.
Actually, i'd argue that a sufficient quantity of properly-chosen (and named...) private methods not only makes the code more readable, but also effectively eliminates most scenarios where internal booleans, long conditionals, or gotos might otherwise be used. And that's a good thing. ;)
----
...the wind blows over it and it is gone, and its place remembers it no more...
Shog9 wrote:
No, it's because i don't need it.
It's not ever necessary, no, but my question is, can it make things more readable sometimes? Is it being unnecessarily demonized?
Shog9 wrote:
Actually, i'd argue that a sufficient quantity of properly-chosen (and named...) private methods not only makes the code more readable, but also effectively eliminates most scenarios where internal booleans, long conditionals, or gotos might otherwise be used. And that's a good thing.
That means several things though: -I have to scroll up and down to jump between methods -I have to choose the locals that I want to use (not so bad with Refractor) -If I ever want to change those locals, I have to change the code in two locations: the call arguments and the method parameters -I have to sit down and think of a name. And I spend a lot of time coming up with good names, because if I don't, it affects my reasoning later on.
Shog9 wrote:
or gotos might otherwise be used. And that's a good thing.
Sure, but why?
-
Christian Graus wrote:
Not sure what you mean by 'making private methods for the sake of avoiding goto', if you have code that needs to be pointed to only sometimes, refactoring it to a new method just makes sense.
Eh, now that you ask, I can't think of any examples. Maybe you have a point. So what makes it bad if you know not to use it in a bad way?
There is no circumstance in which it doesn't create code that's less readable than if you use a method to call, or try/catch. I've simply never looked at code I wrote and thought 'if only I could use goto'.
Christian Graus - Microsoft MVP - C++ "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
-
Christian Graus wrote:
The closest I would get is to regard goto as another way to handle code that is at least as well handled by try/catch.
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dll
A first chance exception of type 'System.NullReferenceException' occurred in mscorlib.dllxacc.ide
IronScheme a R5RS-compliant Scheme on the DLR
The rule of three: "The first time you notice something that might repeat, don't generalize it. The second time the situation occurs, develop in a similar fashion -- possibly even copy/paste -- but don't generalize yet. On the third time, look to generalize the approach."I'm sure your point is obvious to you, but it escapes me
Christian Graus - Microsoft MVP - C++ "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
-
Shog9 wrote:
No, it's because i don't need it.
It's not ever necessary, no, but my question is, can it make things more readable sometimes? Is it being unnecessarily demonized?
Shog9 wrote:
Actually, i'd argue that a sufficient quantity of properly-chosen (and named...) private methods not only makes the code more readable, but also effectively eliminates most scenarios where internal booleans, long conditionals, or gotos might otherwise be used. And that's a good thing.
That means several things though: -I have to scroll up and down to jump between methods -I have to choose the locals that I want to use (not so bad with Refractor) -If I ever want to change those locals, I have to change the code in two locations: the call arguments and the method parameters -I have to sit down and think of a name. And I spend a lot of time coming up with good names, because if I don't, it affects my reasoning later on.
Shog9 wrote:
or gotos might otherwise be used. And that's a good thing.
Sure, but why?
I find that private methods help me read and understand code better. Compare
void ProcessResults(Data d)
{
if (d.cond1 && (d.cond2 || d.cond3)
{
...
}
}with
void ProcessResult(Data d)
{
if (IsType1(data)
{
...
}
}private bool IsType1(data)
{
return data.cond1 && (data.cond2 || data.cond3);
}When reading ProcessResult, I don't need to figure what the boolean logic is trying to do (another layer of abstraction, if you will). This keeps the focus on ProcessResult's code flow
Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | My Flickr | WinMacro
-
I find that private methods help me read and understand code better. Compare
void ProcessResults(Data d)
{
if (d.cond1 && (d.cond2 || d.cond3)
{
...
}
}with
void ProcessResult(Data d)
{
if (IsType1(data)
{
...
}
}private bool IsType1(data)
{
return data.cond1 && (data.cond2 || data.cond3);
}When reading ProcessResult, I don't need to figure what the boolean logic is trying to do (another layer of abstraction, if you will). This keeps the focus on ProcessResult's code flow
Regards Senthil [MVP - Visual C#] _____________________________ My Blog | My Articles | My Flickr | WinMacro
I don't think I'd ever name a method ProcessResults. Well, maybe I have in the past. If it's an override or interface implementation or something and I have no option but to use that name, and the logic isn't straightforward, I'd just comment it. Especially if it involves any sort of math.
-
Shog9 wrote:
No, it's because i don't need it.
It's not ever necessary, no, but my question is, can it make things more readable sometimes? Is it being unnecessarily demonized?
Shog9 wrote:
Actually, i'd argue that a sufficient quantity of properly-chosen (and named...) private methods not only makes the code more readable, but also effectively eliminates most scenarios where internal booleans, long conditionals, or gotos might otherwise be used. And that's a good thing.
That means several things though: -I have to scroll up and down to jump between methods -I have to choose the locals that I want to use (not so bad with Refractor) -If I ever want to change those locals, I have to change the code in two locations: the call arguments and the method parameters -I have to sit down and think of a name. And I spend a lot of time coming up with good names, because if I don't, it affects my reasoning later on.
Shog9 wrote:
or gotos might otherwise be used. And that's a good thing.
Sure, but why?
reinux wrote:
It's not ever necessary, no, but my question is, can it make things more readable sometimes? Is it being unnecessarily demonized?
No. Well, yeah, probably - i mean, why bother to demonize a keyword, even if it is generally misused by people who don't know what they're doing. But i'd say it's use is discouraged and rightly so. Look, goto is primitive, a very simple building-block. Unconditional transfer. Right? But the thing is, you always want conditional transfer. Think about it - you'll always use some sort of conditional to control whether or not the goto is ever reached. This is old stuff, bordering on the
je | _ne stuff |_ jmp
assembler pattern or similar. It's tedious, hard to read, and error-prone, which is why we've spent decades building wrappers into the languages themselves. The other unconditionals have very strict limits on them -break
,continue
,return
... all transfer control, but in very specific ways. You see a return, you know you're done with the current method. You see a break, you know you're leaving the current loop (or switch...), etc. You read them and, provided you're keeping your methods and loops fairly short, can know immediately what's going to happen.goto
is more of a wildcard... you can't read it without wondering what sort of odd thing is happening such that more limited control structures couldn't be used in place. I mean, heck - you can simulate subroutines withlongjmp()
too, but why would you want to? ;) And yeah, it can make things more readable sometimes. Usually when things are next-to-unreadable already, and your only other hope of avoiding complete disaster is to re-write the whole mess. Which is fine, but not a good reason to start looking for excuses to work them into brand-new code.reinux wrote:
That means several things though: -I have to scroll up and down to jump between methods
If you want to read or trace through every single line of code, you'll be scrolling and jumping around anyway. If you're just trying to get a clear high-level picture of the logic or to find one particular area, now you'll have a ready index to help you.
reinux wrote:
-I have to choose the locals that I want to use
Well... duh. How is this relevant? Do you normally work off of a big fa