Live data from Hacker News

GOTOphobia considered harmful in C

blog.joren.ga

261–270 of 319 posts

Re: GOTOphobia considered harmful in C

#261

Earlier quoted context omitted.

That's not really a fair complaint against C, when many safer languages whose syntax derives from C (e.g. javascript) would have the same problem.

It's a fair complaint against C and JavaScript.

And Java, C#, C++ etc. But whitespace-sensitive languages dot not have the issue.

Re: GOTOphobia considered harmful in C

#262

Earlier quoted context omitted.

CONTINUE and BREAK are simply jumps to the beginning of or just past the end of the current loop context. They are equivalent to GOTOs to particular program offsets without the programmer needing to create labels for those offsets. They do not have any magical meaning beyond that. You could even call them syntactic sugar.

Yes, it's all compiled to jumps... The point of the discussion is that things like continue and break are easier to read and reason about because they can't just jump anywhere .

My point was to contest GP's assertion that CONTINUE and BREAK were not equivalent to GOTOs.

I agree that CONTINUE and BREAK are easier to reason about because you can look at them and instantly know what they do without having to look up what label they're jumping to.

Re: GOTOphobia considered harmful in C

#263
As a kid I once saw a quicksort implemented in BASIC and it looked like magic to me. I thought how could anyone come up with this algorithm….

Then I saw it implemented recursively in lisp…it was the simplest most obvious choice to make, and it was hard to imagine anything else.

Now I think that the BASIC implementation must have been a translation from the lisp or something equivalent and it would have been very unlikely that any native BASIC programmer would have come up with it on their own. Of course it used GOTOs.

With the proper abstraction level any complex algorithm becomes trivial.

Re: GOTOphobia considered harmful in C

#264
post #234

Earlier quoted context omitted.

> CONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope CONTINUE, BREAK, and GOTO all operate predictably because they are deterministic operations. Each continues program execution at the directed explicit (goto) or implicit (continue or break) offset. There is no non-deterministic or unpredictable behavior whatsoever.

> operate predictably because they are deterministic operations If I sat you in front of a computer generating numbers using a pseudo random number generator and gave you as context the last number it generated, could you make any prediction about the next number it generates? Now if it used a prng that was known and standardized to only compute one number could you predict anything about the next number now?

[deleted]

Re: GOTOphobia considered harmful in C

#265
post #249
post #20

If you’ve ever actually written more than toy C, you’ll know gotos are essential for resource cleanup and error handling. Even the famous goto fail was not a goto error, it was a block error (named because a cleanup statement `goto fail;` always executed because of a brace-less if). goto can be abused like any other language construct, but it’s uniquely useful and makes code more simple and easy to reason about when…

Not really, I have deployed plenty of C code into production and never used gotos, other than special flavoured gotos like UNIX signals. My problems have always been in how memory corruption friendly C happens to be, nothing to do with how to use structured programming practices for resource cleanup.

I don't see any similarity between gotos and signals at all. Gotos are just explicit jumps, while the "normal" structured way of doing jumps is to have them inferred from nested regions (that double as scopes and lifetime guards for automatic variables).

The structuredness of such inferred jumps usually is both sufficient and convenient, but sometimes being extremely structured leads to boilerplate and inefficiencies. That shows already with early returns from nested scopes, which aren't widely frowned upon, while they are very similar to common usage of goto. I would say I haven't encountered a goto that isn't basically an early return from some nested scope to after some parent or grand-parent scope.

In that sense, a goto can save from having to extract a nested scope as a stand-alone function just to write it as an early return. I would say that many gotos in the wild could be rewritten as early returns after making a standalone function, but maybe sometimes this is too much of a hassle, or, subjectively, puts a toll on readability.

Re: GOTOphobia considered harmful in C

#266

Earlier quoted context omitted.

> Labeled break and continue ... I find that normally if I need nested break then it suffices to refactor the target loop into a function and use return instead. I don't think I normally miss multilevel continue, but the same strategy would work for that too. You'd just pull out the target loop body rather than the whole loop. If that doesn't work because you need to select too many different break/continue levels (m…

> You'd just pull out the target loop body rather than the whole loop. that's a "good solution" in the sense of "lambda is the ultimate goto", but if you're writing a loop over the rows and columns (or more dimensions) of something, pulling out and segregating the control structure for the innermost (and potentially other) layers of the hierarchy can make a simple depth first exploration look obscure. If the total am…

That sounds like a case where some sort of iterator class would be best (or, in C, an iterator "class" made of a struct with associated functions). It could have helper methods for .next_column() etc., and you'd just have one overall loop.

That might make the code more complicated, overall, but that's the trade off of structured programming - occasionally there's more complexity but it's so exceptionally rare that it's still worth it overall. (Then again ... perhaps it would make the code arguably simpler anyway.)

Re: GOTOphobia considered harmful in C

#267
post #249

Earlier quoted context omitted.

Not really, I have deployed plenty of C code into production and never used gotos, other than special flavoured gotos like UNIX signals. My problems have always been in how memory corruption friendly C happens to be, nothing to do with how to use structured programming practices for resource cleanup.

I don't see any similarity between gotos and signals at all. Gotos are just explicit jumps, while the "normal" structured way of doing jumps is to have them inferred from nested regions (that double as scopes and lifetime guards for automatic variables). The structuredness of such inferred jumps usually is both sufficient and convenient, but sometimes being extremely structured leads to boilerplate and inefficiencies…

Signals are implicit GOTOs in the sense of INTERCAL's COMEFROM.

As for structured handling, instead of gotos all over the place, do inverted conditions for early returns similar to what Swift has done with guard statement, embrace functions for resource cleanup, if the cost of a jump brings cold sweat, have them inline and called alongside a return, most compilers will replace calls with jmp opcodes.

Re: GOTOphobia considered harmful in C

#268
post #267

Earlier quoted context omitted.

I don't see any similarity between gotos and signals at all. Gotos are just explicit jumps, while the "normal" structured way of doing jumps is to have them inferred from nested regions (that double as scopes and lifetime guards for automatic variables). The structuredness of such inferred jumps usually is both sufficient and convenient, but sometimes being extremely structured leads to boilerplate and inefficiencies…

Signals are implicit GOTOs in the sense of INTERCAL's COMEFROM. As for structured handling, instead of gotos all over the place, do inverted conditions for early returns similar to what Swift has done with guard statement, embrace functions for resource cleanup, if the cost of a jump brings cold sweat, have them inline and called alongside a return, most compilers will replace calls with jmp opcodes.

> Signals are implicit GOTOs in the sense of INTERCAL's COMEFROM.

What?

> guard

How does it help to have an inverted if statement? Not sure what is the point, can do without.

Goto isn't necessarily for resource cleanup. The common usage is as an early break from the currently executed block, to what comes after the block. Which is often cleanup code, but not necessarily.

Re: GOTOphobia considered harmful in C

#269
post #237

Earlier quoted context omitted.

Sure it's possible to have horrible spaghetti today. Just look at any pubsub architecture based system and tell me what piece of code executes after another. It's super popular, and it's GOTOs all over again, just with data instead.

This is a good observation, thanks. Yes, some of these cloud-native patterns do become what is essentially a spaghetti flow pattern, even if not in the fragmented pieces of code directly.

It's not just cloud, ROS uses this for robotics, for example.

Re: GOTOphobia considered harmful in C

#270

Earlier quoted context omitted.

Yes, it's all compiled to jumps... The point of the discussion is that things like continue and break are easier to read and reason about because they can't just jump anywhere .

My point was to contest GP's assertion that CONTINUE and BREAK were not equivalent to GOTOs. I agree that CONTINUE and BREAK are easier to reason about because you can look at them and instantly know what they do without having to look up what label they're jumping to.

IF and WHILE are also equivalent to GOTOs in that sense.

The point is that CONTINUE and BREAK jump to exactly one location given their lexical context and cannot jump anywhere else. They are also only meaningful when applied to structured control flow. The problem with GOTO is the unbound nature of its jump target, which leads to control flow that is difficult to comprehend by looking at the lexical structure of a function.

Post reply on HN