9 ms·
> We also generally agree, in 2012, that goto is flat-out inappropriate for source code in most modern programs. Exceptions to this policy exist, but they’re ex
by jbk 14y ago
> We also generally agree, in 2012, that goto is flat-out inappropriate for source code in most modern programs. Exceptions to this policy exist, but they’re extremely rare.
No, we don't agree. In C, goto is very often the best way to deal with error paths. It is used in the Linux kernel and in many other important (open source or not) applications.
I doubt those qualify as rare.
- alexchamberlain 14y agoOo I agree, see my comment at the same time!
- koide 14y agoWell, C isn't a particularly modern language.
- alexchamberlain 14y agoYes, but a lot of software is written in C and continues to be written in C. There isn't really a replacement.
- glassx 14y agoI like the position of this C2 article on goto: http://c2.com/cgi/wiki?GotoConsideredHarmful http://c2.com/cgi/wiki?GotoConsideredHarmful It argues that forward gotos (that work like continue, break, returns mid-function) don't contribute to spaghetti code, while backward gotos are more problematic.
- lubutu 14y agoAnd yet backward goto is extremely useful. Consider this Java, redo: while(true) { for(Item x : xs) if(f(x)) continue redo; break; } With goto, redo: for(Item x : xs) if(f(x)) goto redo; Most people seem at first to balk at the goto, even though they're functionally identical, and the goto is much clearer and less error prone...
- glassx 14y agoThe article mentions that as well: "Backward gotos could be ok when it makes sense that your error case would repeat the last iteration" Btw, in Ruby there are two keywords that are basically backward gotos: redo and retry.
- einhverfr 14y agoThat's the exact case where I saw it in the PostgreSQL code. Re-doing join pruning when a join was eliminated.
- ajanuary 14y agowhile (xs.Any(x => f(x))) { } Pulling things out into other functions makes it even clearer. Though yes, the goto is clearer than the labelled continue. I wouldn't necessarily agree that it's less error prone though.
- lubutu 14y agoWell, if we permit functional programming languages all the problems concerning imperative control flow magically go away...
- ajanuary 14y agoI just used higher order functions to keep the example short, and I'd use them irl to avoid code repetition. The concept still applies without them: while (fTrueForAny(xs)) { } boolean fTrueForAny(List xs) { for (Item x : xs) { if (f(x)) { return true; } } return false; } There isn't anything non-imperative about higher order functions. var externalDataStore = new ExternalDataStore() [1, 2, 3, 4].each(x => externalDataStore.store(x)) externalDataStore.getItems().each(item => print(item)) Plenty of higher order functions, and plenty of non-functional, ordered, stateful, imperative code.
- dmethvin 14y agoAgreed, for languages like C. It's not just error paths, either. For example, to break out of an outer loop inside an inner one you can label the outer loop with OUTER and use `last OUTER` in Perl or `break OUTER` in Java/JavaScript. But in C you have to either use a goto or (shudder) tinker with the outer loop control variable and break from the inner loop.