> On the other hand, today we have the very opposite situation: programmers not using goto when it's appropriate and abusing other constructs, what ironically makes code only less readable. One I see all the time from beginners is creating a finite state machine using one method per state and jumping between states by calling the next state’s method from within the current state’s method. Essentially just emulating g…
This is one of those problems that Tail Call Elimination cleanly addresses. The "obvious" approach to writing an FSM does exactly what you'd expect.
GOTOphobia considered harmful in C
171–180 of 319 posts
Re: GOTOphobia considered harmful in C
#172Earlier 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…
To give people some kind of an idea of what it was created in response to: Imagine writing an entire program in one single main function. The only thing you're allowed to do for flow control is goto. You can do 'goto somelabel;' for an unconditional goto, or you can do 'if (somecondition) goto somelabel;' for a conditional goto. Here's some examples of how it would look if if translated to something C-like: Loops wou…
Re: GOTOphobia considered harmful in C
#173Earlier quoted context omitted.
Early Fortran already had loops, but with labels: INTEGER A(4,4), C, R ... DO 10 WHILE ( C .NE. R ) A(C,R) = A(C,R) + 1 C = C+1 10 CONTINUE Note that Fortran has evolved significantly over time. This is how you would write the same in Fortran 77: INTEGER A(4,4), C, R ... C = 4 R = 1 DO WHILE ( C .GT. R ) A(C,R) = 1 C = C - 1 END DO
Those are just regular loops, though, right? I’m looking for the posttest loop, sometimes known as the do…while or until loop. There seems to be a unfortunate inconsistency in the naming of this thing.
> There seems to be a unfortunate inconsistency in the naming of this thing.
Well, Fortran is older than C, so you cannot really blame them :-)
Re: GOTOphobia considered harmful in C
#174In 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…
> 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…
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 amount of code is fitting in a screenful, I'd rather put multi-level break or continue labels and then goto them sparingly.
Re: GOTOphobia considered harmful in C
#175Earlier quoted context omitted.
Yes. There's a reason pretty much every secure C coding standard dictates exact what I said, like CERT C etc. There's a reason they have weird bugs. Just because it's an impressive piece of software, doesn't mean it can't have horrible design pattern written by substandard coders. And in an open source project with as many contributors as Linux, I would say it's not hard to fathom that there's a significant number of…
or maybe its that things like a kernel reasonably need to use goto? or at least at the time it was written, there werent alternatives that were performant enough.
Re: GOTOphobia considered harmful in C
#176Earlier quoted context omitted.
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.
Crashing makes sense in these scenarios if the application is only doing one thing. But I am usually working on multi-user servers. I would rather fail out the current request, but allow concurrent requests from other clients to continue.
Yes, I understand the argument: "But if something unexpected happened, your application could be left in a bad state that causes other requests to fail too. It's better to crash and come back clean."
This is not my experience in practice. In my experience, bad states that actually poison the application for other requests are extraordinarily rare. The vast, vast majority of exceptions only affect the current request and failing out that request is all that is necessary. Taking down the whole process is not remotely worth it.
Moreover, crashing on assertions has the unintended consequence of making programmers afraid to write assertions. In a past life, when I worked on C++ servers at Google, assertion failures would crash the process. In this argument, I saw some people argue that you should not use assertions in your code at all! Some argued for writing checks that would log an error and then return some sort of reasonable default that would allow the program to continue. In my opinion, this is an awful place to end up. Liberal use of asserts makes code better by catching problems, making the developer aware of them, and avoiding producing garbage output when something goes wrong.
Re: GOTOphobia considered harmful in C
#177I 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…
Sure, but that has nothing to do with whether the GOTO statement should be used. The semantics of GOTO are arguably quite clear; they amount to setting a different continuation for the running program. (Semantically, this implies that the precondition of the GOTO statement is made a possible precondition for the label that the statement jumps to; and execution simply does not proceed to the next statement.)
There are even "relooper" algorithms to reconstruct a structured program from patterns in the idiomatic use of GOTO statements: they are used in compiling to structured object languages such as WASM code. Using GOTOs in an idiomatically sensible way (avoiding spaghetti code) may be less readable than writing actual structured blocks, but only slightly so.
Re: GOTOphobia considered harmful in C
#178Re: GOTOphobia considered harmful in C
#179Earlier 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…
This. To find an example, I did a search for “Commodore PET Basic programs”. Here’s a book from 1979 that shows what spaghetti code looks like, in my opinion: http://www.1000bit.it/support/manuali/commodore/32_BASIC_Pro... The first program listing is on page 24 of the PDF. Try to follow the logic of the program. Why does line 400 go to 280? What paths can lead to line 400? Who knows! And this is high-quality BASIC b…
Without looking at the post-program material, this isn't exactly a difficult question to answer.
Line 400 is preceded by some print statements:
370 PRINT "PRESS 'E' TO END, SPACE TO CONTINUE"
380 GET R$:IF R$="" THEN [goto] 380
390 IF R$="E" THEN [goto] 120
400 L=0:GOTO 280
So we have a prompt that says "press E to end, space to continue", and then branches one of three ways: if you provide no input, the prompt is shown again; if you provide an E, the entire program restarts from scratch, and if you do anything other than that, the count of lines drawn on screen is reset to 0 and the next 18 lines of the chart are drawn.We can assume that line 400 will be hit whenever a piece of chart is drawn to the screen.
The program's structure here is a nested loop: there is a loop between lines 280 and 400 (displaying the chart indefinitely, 18 lines at a time) containing another loop between lines 300 and 360 (displaying 18 lines of a chart, one line at a time).
Why is this supposed to be an example of spaghetti code?
Re: GOTOphobia considered harmful in C
#180Exceptions are GOTO's. Sure, it's more likely to be safe in terms of memory/resource leaks, but in terms of program logic it is no different.
Returns are also gotos then.
But there is a good case to be made that exception handlers are gotos in the Dijkstra sense, at least when used for anything other than exceptions, like passing errors around.