The "goto cleanup" idiom to do deferred work (I don't like defer or finally in languages which have them, but at least these are language constructs which say what we wanted, the goto cleanup idiom only achieves that in some very easy cases, in more complicated cases your actual intent will be unclear)
The "iterator escape" idiom to get out of some larger iterative operation we're doing because we just realised we want to give up / found the overall answer. This is lack of imagination in the language's / library's / eco-system's control flow semantics and is one reason I really like Rust's core::ops::ControlFlow.
Code shouldn't require imagination. Sometimes the simple and readable solution is just better.
I occasionally have a couple of returns in one func but only for very, very simple and short funcs where it's clearer.
I dunno. Perhaps the problem is we're missing some higher level procedural construct - any ideas?
Doing if(condition) return at the start, before it gets going often reduces indentation and how many branches you need to see at once.
But I can agree sneaky returns can bite you sometimes
Examples I was thinking about:
* an early return can only go back to the call-site
* all returns in a function or method return to the same place
* an early return terminates the context it is in
* an early return does not create an entry point for nearly arbitrary other code points as labels for gotos do
Those few places where they appear in (what would have been) defensible C code are better served by reliance on destructors. I.e., it is much better to start compiling the C code with a C++ compiler, and then clean it up.
- In some very performance sensitive cases. It helps you skip a bunch of extra checks or variables.
- When you need to convert recursion to iteration, but want to keep the code structure mostly intact so you don't mess up the source control history.
Nowadays I will use lambdas that return early in preference to goto. Not from fastidiousness so much as to avoid confusing the optimizer.
Poster child for reprehensible use of goto is procmail.
switch n{case 1: case 2: case 3:}
would become e.g. goto n*100+1000
with lines 1100,1200,1300 handling the cases.And then there was the hidden advanced troubleshooting console:
input N: GOTO N choice /c abc
goto choice%errorlevel%
:choice1
:choice2
:choice3
Or, for command-line parameters: set ops=a b c
set op=%1
for %%p in (%ops%) do if "%op%"=="%%p" goto %op%
goto usageDijkstra was wrong with his “goto” paper. It’s fine to admit that. He was right about most other things.
> The paper doesn't explain to us what would be the use of the "if" statement without a "goto" to redirect the flow of execution: Should all our postconditions consist of a single statement[…]?
It made perfect sense back when people were writing BASIC full of "GOTO 110" and "GOTO 520" that resulted in a tangled mess. Unfortunately it caught on so well that it resulted in people being really obsessive about it, and rejecting every single instance of it in C code, even in places where it makes perfect sense and makes the code cleaner.