Re:The Evolution of C Programming Practices: A Study of Unix...
by kevin_thibedeau on Friday May 11, 2018 @10:49AM
(#17047664)
Tracing through goto spaghetti is not more comprehensible than a structured switch with clearly defined regions for each state. This is the sort of abuse that gives goto a bad name. The only thing worse is table driven state machines calling function pointers scattered everywhere.
Re:The Evolution of C Programming Practices: A Study of Unix...
by colanderman on Friday May 11, 2018 @10:59AM
(#17047734)
State machines implemented with gotos have very clearly defined regions for each state: the space between each label. Switch-based state machines are fine, but become hard to follow when e.g. you need a loop around a couple states, and are often abused to allow changing states from a non-lexically-local context (e.g. within a function call).
At a high level, this:
goto NewState;
is no less comprehensible or spaghetti-prone than this: state = NEW_STATE;
break;
(No, you can't use tail calls to represent state machines in C; that is not a feature of the C language but rather of a given implementation. And yes, you could model state machines with an enum variable and a big switch statement, but that's even harder to follow.)
What trips people up is when goto is used to jump across resource lifetime boundaries (which C++ addresses with RAII), when they maintain too much state in cross-state variables that they forget what their invariants are, and when they use a goto as a replacement for what should be a function call.
Using goto to implement e.g. a data processing loop, a non-recursive graph traversal algorithm, or a parsing state machine are all perfectly valid uses.