Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There are several good uses for goto in C. Here's a few I can think of, off the top of my head:

1. Breaking out of nested loops. Sure, you can kludge this with a flag variable, but goto is far more readable.

2. Implementing resource cleanup with stack-style unwinding semantics (i.e. RAII-like). The alternative is usually a bunch of nested if statements, which makes things much harder to read.

3. Implementing state machines. goto is very good at expressing transitions in a graph-like state machine. It doesn't inflate code size as using inline functions would, and it doesn't incur register/stack setup costs that non-inline functions would. However, readability becomes somewhat difficult as the state machine gets more complex, so this is usually relegated to code generators like SMC, re2c, or Ragel.

4. Dispatch loops for threaded virtual bytecode. This is especially niche, and it relies on the labels-as-values gcc extension, but it is very important for implementing performant interpreters.

The average C programmer won't necessarily encounter all of these use cases in their career, but that doesn't make any individual one any less important.



Part of GP's point is that none of those are "real" gotos. C doesn't have them. C has a construct called "goto" which resembles goto the way that a vacuum cleaner resembles a black hole. A constrained, neutered, much safer shadow of the real thing.

If anything, the value of C's goto is evidence in favor of Dijkstra's argument more than against it. Real-world programs don't need real gotos, and the situations where you want them are perfectly well-served by constrained, limited replacements. Like function calls, for-loops, and the thingy that C calls a "goto."

For the sake of completeness: there's two main ways in which C's gotos are limited. The first is that they are function-scoped, the second is that they are declared labels rather than arbitrary program points. We nowadays consider that encapsulating data is a good thing. The idea of encapsulated control flow is so taken-for-granted that we don't even realize it could otherwise, but that's effectively what a true goto is.


For state machines nothing beats tail calls. Those are effectively a goto, but much more expressive and readable. Too bad those are not implemented in supposedly high-performance popular languages.


> Too bad those are not implemented in supposedly high-performance popular languages.

Perhaps a nitpick: you presumably mean tail-call optimisation, which isn't the same thing as a tail-call.

To my knowledge modern C compilers are generally able to perform the optimisation.

I believe Java has a hard time with tail-call optimisation as its exception-handling features require it to faithfully track the call stack in case an exception is thrown.


> Perhaps a nitpick: you presumably mean tail-call optimisation, which isn't the same thing as a tail-call.

Tail calls consuming unnecessary stack space is a common pessimisation.


Yes, GCC can do tail-call optimization. What you can't do is rely up on in C. Lua has tail-call optimizations and because of that, you can rely upon it. There is a difference.


Right, some languages guarantee tail-call optimisation in the language spec itself. The C standard doesn't do this.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: