Live data from Hacker News

GOTOphobia considered harmful in C

blog.joren.ga

121–130 of 319 posts

Re: GOTOphobia considered harmful in C

#121
post #22
post #10

> Bad code is the product of bad programmers This person is living in a pretend bubble that isn't grounded in the reality of large projects, multiple team members, deadlines, changing requirements, etc. No programmer is perfect. And when your tool can cut your arm off, you should be careful or route around the dangerous bits when possible.

This analogy implies that all other tools are 1000% safer, but they are not. In C it’s like pointing to a dusty corner behind a table in a room full of dirt. When was the last time you did “cut your arm” with goto specifically? What’s the count and time ratio to other issues? Were these also addressed as taboo or left as “experience earned”? Gotophobia in its largest part is just a stupid meme with no real world data…

> This analogy implies that all other tools are 1000% safer, but they are not.

What an oddly specific presumption.

Re: GOTOphobia considered harmful in C

#122

Earlier quoted context omitted.

If you have ever seen someone try an construct a bunch of nested IF statements with complicated conditional clauses you might think GOTO is not so bad. People have simply become better coders. There are also still GOTOs that are used in specific cases such as CONTINUE and BREAK - no labels required. If I look back it always comes back to naming and managing names of things. GOTO 100 is meaningless and one eventually…

CONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope: their limitations make them incapable of creating the unstructured nightmare that Dijkstra was talking about. They're similar to a GOTO only in that they compile to a jump, but so do IF statements and FOR loops. Structured programming wasn't about eliminating jumps, it was about enforcing discipline in their use…

The argument against gotos in Dijkstras article would apply equally to breaks and continue and even to early returns.

I dont fully agree with Dijkstras argument. For example I think early returns can often improve the readability of the code. But worth noting Dijkstra is not primarily concerned about readability but rather about how to analyze the execution of a program.

Re: GOTOphobia considered harmful in C

#123
post #77
post #50

I always encourage people to go read Dijkstra's GOTO paper, instead of just its title. It's a short and easy read, almost like a blog post. If you pay attention, you can see that the he was talking about spaghetti code vs structured code. It's better when the lexical structure of the source code maps to the execution structure. That is, if you know what is the current line being executed, you have a good idea of what…

The thing is that many people today have never encountered the sort of spaghetti code that Dijkstra was talking about in 1968. There's plenty of confusing and messy code around, but true spaghetti code that GOTOs all over the place and is nigh-impossible to follow has been extremely rare for a long time. I can't recall encountering it in the last 30 years. It easy to misunderstand what he was even talking about becau…

[deleted]

Re: GOTOphobia considered harmful in C

#124

Earlier quoted context omitted.

If you have ever seen someone try an construct a bunch of nested IF statements with complicated conditional clauses you might think GOTO is not so bad. People have simply become better coders. There are also still GOTOs that are used in specific cases such as CONTINUE and BREAK - no labels required. If I look back it always comes back to naming and managing names of things. GOTO 100 is meaningless and one eventually…

CONTINUE and BREAK are quite different from GOTO in that they operate predictably given the current scope: their limitations make them incapable of creating the unstructured nightmare that Dijkstra was talking about. They're similar to a GOTO only in that they compile to a jump, but so do IF statements and FOR loops. Structured programming wasn't about eliminating jumps, it was about enforcing discipline in their use…

Not too many things make me shake my head harder than folks who consider continue/break to be GOTO equivalents. For the reasons you eloquently said.

Additionally, far more often than not, continue/break allow you to avoid another form of complexity, bugs, and low comprehensibility: deeply nested conditionals.

Re: GOTOphobia considered harmful in C

#125
post #97
post #77

Earlier quoted context omitted.

The thing is that many people today have never encountered the sort of spaghetti code that Dijkstra was talking about in 1968. There's plenty of confusing and messy code around, but true spaghetti code that GOTOs all over the place and is nigh-impossible to follow has been extremely rare for a long time. I can't recall encountering it in the last 30 years. It easy to misunderstand what he was even talking about becau…

> The thing is that many people today have never encountered the sort of spaghetti code that Dijkstra was talking about in 1968. Can't highlight this enough. The type of spaghetti code "goto considered harmful" was reacting to is basically impossible to create anymore, so anyone who didn't work on that type of code in the 80s or earlier probably hasn't seen it. And thus, is applying the mantra "goto considered harmfu…

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.

Re: GOTOphobia considered harmful in C

#126
post #53

Earlier quoted context omitted.

"The problem isn't C, it's that they weren't using C properly..."

But that is a legitimate problem. Using a language feature that is a known footgun (`if ...` instead of `if {...}`) without being cautious enough to avoid shooting yourself in the foot is not the fault of the footgun, it's the fault of the programmer. Additionally, in the above linked case, the problem isn't a misused `goto`, it's a misused `if ...`. It would be just as problematic if they typed `cleanup_context();`…

Once a footgun shoots the feet of enough people, the problem is no longer with the people, it is with the thing that enables the footgun.

Re: GOTOphobia considered harmful in C

#127
The state machine example is definitely a very fitting use of goto, but it reminds me of another thing that seems to have become a rare skill but is very useful: flowcharting. Besides making people comfortable with goto in general, it also helps visualise control flow in ways that a lot of programmers these days don't realise, and it's unfortunate that a lot of courses seem to have omitted its teaching.

Also worth reading is "GOTO Considered Harmful Considered Harmful": https://news.ycombinator.com/item?id=11056434

And here Microsoft provides us with lovely example of such ridiculous nesting.

That's a very memorable example, but ultimately the true cause of that monstrosity is a clearly stupid API design; this is the API for a file picker, the recommended replacement for an existing one that they wanted to deprecate. In the existing one, you fill in a structure and call a single function with a pointer to it. In its replacement, you need to call a dozen methods on an object, and check for "possible" errors on each call, even if probably 99% of them only do things like assign to a field in a now-opaque structure and can never produce an error. Then the example code must've been edited by someone with severe gotophobia. (Not all MS code is like that --- they have plenty of other example code that uses goto, e.g.: https://github.com/microsoft/Windows-driver-samples/blob/mai... ) The existing API was even extensible, since it used a structure with a size field that could differentiate between different versions and extensions, but they didn't.

Re: GOTOphobia considered harmful in C

#128

In RAII languages[0], you obviously don't need unrestricted gotos. However, I always find myself missing it when writing nested loops. Labeled break and continue[1] ought to be considered standard structure programming primitives. These are restricted gotos and allowing them to break or continue a parent loop doesn't unrestrict them much. But it does significantly improve the expressive power of your looping construc…

Even with RAII in C++, goto is still useful for handling the occasional error case where you need to reset/retry some operation e.g. due to transient hardware issues that are not unrecoverable errors. A common example that comes to mind immediately is asynchronous disk reads where the data was corrupted during transfer but may succeed if transparently cleaned up and re-issued. I use goto rarely. But there are times w…

Gotos are quite nice for some state machines too. You essentially store the state in the instruction pointer instead of some helper variable.

Re: GOTOphobia considered harmful in C

#129
post #46

This is fun! The C version; int foo(int v) { // ... int something = 0; switch (v) { case FIRST_CASE: something = 2; goto common1; case SECOND_CASE: something = 7; goto common1; case THIRD_CASE: something = 9; goto common1; common1: /* code common to FIRST, SECOND and THIRD cases */ break; case FOURTH_CASE: something = 10; goto common2; case FIFTH_CASE: something = 42; goto common2; common2: /* code common to FOURTH a…

> The nested functions usually get inlined by the compiler, so there is no cost to them. This kind of code typically gets written when ‘usually’ isn’t good enough (of course, once you use a compiler, in theory, there are no guarantees; the compiler could compile the inlined-function one with a goto or vice versa, but programmers typically are more concerned about what happens in practice) The inlined functions also m…

When it isn't good enough, inserting `pragma(inline, true)` will force it.

> The inlined functions also may increase code size and instruction cache pressure.

tail merging optimization takes care of that

Re: GOTOphobia considered harmful in C

#130
post #66

Earlier quoted context omitted.

You can, and your program will call std::terminate if there’s already an exception being processed. Not exactly desirable if you’re trying to write code that ensures careful resource cleanup. Also why it’s widely regarded as _wrong_ to ever throw in a destructor.

IMO this is a design bug in C++. The authors couldn't agree on what to do in the exception-during-unwind scenario, so they chose the worst possible option: crash. In most cases, an second exception raised while another exception is already being thrown is merely a side-effect of the first exception, and can probably safely be ignored. If the idea of throwing away a secondary exception makes you uncomfortable, then an…

Even if the standard consolidated on one way or another to pack up secondary exceptions (or discard them) how likely is the calling code going to be able to handle and recover from this case?

I am personally on team crash - I would rather my program exited and restarts in a known state then being in some weird and hard to replicate configuration.

Post reply on HN