The Lounge is rated PG. If you're about to post something you wouldn't want your
kid sister to read then don't post it. No flame wars, no abusive conduct, no programming
questions and please don't post ads.
Days ago started to program a driver and remembered me that, altough in some places you can see try/leave/except blocks is modern code, because is programmed in plain C, "goto" is still used a lot mainly for cleanup purposes.
I don't use it in high level languages where there is a structured alternative. The only time I'm tempted is the 'double break', i.e. wanting to escape from two levels of nested looping; to do this you have to create a method to do the double loop and use return, which often feels like overkill.
I've using one while I test some timeout code on a function, but I'll refactor it out before I commit it. Just nice to see the whole process at once for now (and I can make sure it works before I spend time figuring out exactly how to best cleanup before cancelling it).
I have always thought goto was the equlivant of the assembly language jmp (blocking?), if it is I used one this morning. Goto is also acceptable in RTOS situations (which Windows isn't) if you want the valve to close now and not later.
Well as an assembly programmer I really don't have much choice.
And as for higher level languages, sure, though rarely. There are people who religiously avoid it, but that's just silly. We must remember the reason it is seen as bad, and not open a witchhunt.
Introducing a boolean variable just to quit out of a non-enclosing loop makes readability/understandability worse, not better, and refactoring an inner loop into its own function just so you can return out of it creates a bunch of tightly-coupled functions that do nothing useful on their own. Besides, that return would essentially be a goto.
In one of our legacy apps (VB) the goto is used to apply database updates based on the exe version. ErrorHandlers: seperate the update logic for each version and are arranged from top to bottom so that code execution always 'fall through' to the bottom. It may me wrong but it works!
I put it into my own language just because I wanted to see if I could write a program all in one function which started at the bottom and worked its way to the top. I am not sure why, one of those days. I then immediately removed it from the language spec although the code for it is still in the compiler source - just commented out.
I only use it nowadays in assembly (no choice) and scripting languages that don't have good structured programming constructs (ie. if/then/else etc.).
I learned programming in the days of early Fortran IV (and actually regressed a little on an older machine with Fortran IID) that only had arithmetic if[^] and computed goto[^] for conditional logic flow.
I really came to appreciate the evils of the 'goto' statement and never use them unless there is no other choice. If I use a goto, it will always transfer control downwards, never up.
And yes, I use break and continue, and multiple returns in methods.
Many a word has been written about the use of multiple exits being bad practice.
I think I understand the issue from all sides and I don't drink that kool-aid. The way I look at it, the goto takes linear flow and folds it back on itself, causing the programmer to think about an interleaved mesh of logic instead of a stream.
I see the following items as presenting different concepts and approve/disapprove of each on their own merits:
(1) goto backwards within a loop
(2) goto forwards within a loop
(3) goto forwards to exit handler/error handler at end of method
(4) break statement in a loop
(4a) bounded loop
(4b) infinite loop (ie. exit in the middle)
(5) break statement in a switch()
(6) continue statement in a loop
(7) return statement inside a loop (one only per method)
(8) multiple return statements in a method
History has shown that #1 has caused the most problems, and #2 follows closely. #3 seems to be the one that most people defend, and I think it has some merit. I have used #3 but I still avoid it whenever I can. I regularly use all of #4 through #8 and have no problem with them.
Multiple returns in a method are really no different from a break statement in terms of how the programmer's brain processes the logic. Multiple returns cause an exit from a method (so there is no tortured logic flow), you can debug it (eg. you can put a breakpoint on it), do not fold logic back (so that you can get to a statement from multiple directions) and can reduce the amount of code in a method (less code is better code). Probably other things too - this is off the top of my head.