Live data from Hacker News

Goto (2007)

beej.us

61–70 of 207 posts

Re: Goto (2007)

#61
post #4

Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"?

> Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"? There is no need to use GOTO when a language has functions/procedures and exceptions. Of course it makes sense in Assembly…

> There is no need to use GOTO when a language has functions/procedures and exceptions.

... and defer

Re: Goto (2007)

#62
post #17

Earlier quoted context omitted.

Yes, this is pretty much how it is being used in C code. The other acceptable use-case is breaking out of nested loops. There's also `setjmp()`/`longjmp()` but that's even more rarely used.

longjmp() is the C-language version of going-to labels in other functions. Its basic "use" is not having to unwind the stack; but moreover, it lets you avoid cleanup and resource de-allocation. Usually it doesn't make sense to do that (you get memory leaks), but if, say, your memory allocations happen in some kind of arena - you can just leave it in any junk state and then proceed to clear it altogether after your se…

The most common use of setjmp/longjmp I've seen (in embedded development) is to have coroutines in C. The original use AFAIK was usually to implement exceptions of some variety. Neither use is that common these days.

Re: Goto (2007)

#63

Many C/C++ UI frameworks require allocating component parts, linking them together to create an operating widget, and then attaching callbacks and whatnot... The code creating a dialog/window/toolbar with multiple such widgets is a perfect case for using goto to implement a single code block of unwinding of the complex construction of that dialog/window/toolbar. Multiple times I've had long winded debates on why comp…

Maybe so in C, but in C++, stack-allocated container classes, smart pointers, scope guards(!), and (with Qt) the parent-child system can handle almost all cases. Binary size usually increases but lines of code are less or equal to a C-style solution.

It's called RAII, but the main point is really that destructors are automatically called on scope exit.

Re: Goto (2007)

#64
Most programmers and I believe even most teachers see technology not as an application, but as some sort of a blind religion. Shallow understanding only adds to this problem. I’ve seen enough of them saying “what, goto?” in disgust, but almost no one could explain why, apart from saying that it is a taboo and maybe remembering that it was in some book.

They need it, and it’s really good that it was “goto”. If it wasn’t, they would jump on another, more useful bogeyman, like eval.

And for those interested, the specifical use of goto that was considered harmful is its use in place of “for” and “[do-]while” flow control statements and explicit subroutines. Literally:

  loop: …;
  if (!cond) goto loop;

  a = 42; b = 13; goto sub;
  …
  sub: …
It was used as such by inertia, because these were times before invention/adoption of the structured code.

While you may not want to goto into inner scopes for obvious reasons, leaving two loops or goto-ing to a function cleanup section is perfectly okay and is much clearer than breaking the outer loop with a boolean or building ladders of ifs.

Re: Goto (2007)

#65
Another good use of goto is to implement state machines --- "goto state_x" is clearer and simpler than the loop-switch that people often use.

I can certainly say that over the years I've encountered code which was more difficult to understand and less efficient because either the author didn't want to use goto, or the language didn't have it. While it's true that you can always rewrite code to remove goto statements, it can definitely have a negative effect.

Re: Goto (2007)

#66
post #23

When you are forced to follow stupid rules like having only one exit point in a function then goto can be used a lot in place of that, but what are we supposed to do if you are not allowed to both use goto or have multiple returns in a function (in C) ?

> what are we supposed to do if you are not allowed to both use goto or have multiple returns in a function (in C)

Move jobs.

But seriously this is a good point. goto is practically necessary to manage memory in C. Having only one return point is justified in functions that manage heap memory. Standard C has no RAII, defer, finally, or any other alternative but goto.

Re: Goto (2007)

#67
In the past 20 years I've used a goto a few times, and then refactored it out once I was able to look at the problem with a clear head. I remember that, every time, I replaced the goto by breaking up a large method into smaller methods, and then replacing the goto with either return statements or logic that would essentially return.

Yes, a goto is part of our programmers' toolbox. But, now even I consider a "good goto" a sign that a larger method should be broken into smaller ones.

Re: Goto (2007)

#69
post #4

Coming from assembly language, I always found the anti-goto sentiment rather cute. A beautiful restriction, but ultimately arbitrary. Like writing poetry. Or those novels that do not ever use the letter "e". Why would an otherwise sane person write code with "rep" and without ever using "jmp"?

> A beautiful restriction, but ultimately arbitrary. Like writing poetry. This assessment cuts pretty close to the gist of (my reading of) Dijkstra's famous paper that kicked off the anti-goto sentiment, once you take some time to digest the entirety of the paper and consider the context in which it was being written. I'd also like to throw out there, though, that the "go to" statement he describes is a "go to" state…

Right. He was criticizing the version where one subroutine might jump into the middle of another subroutine.

That sort of thing can make safely modifying the second subroutine require knowing if any of its labels are used elsewhere in the program.

It is basically impossible to reason locally when developing like that, unless you first verify that the only uses are local. (Or have applied strict coding standards such that only labels specifically identified can be used as non-local goto targets, etc.)

That sort of thing was extremely normal in say early assembly programming where your code size was so restricted, you needed to reuse code whenever possible. And many early languages brought that sort of capability along with it.

I'd expect Dijkstra's feeling on C's goto would probably be like: Probably a good idea to avoid it when the other control structures work well, but barring silliness like trying to code a large program in a single function, using C's goto for cases not well handled by the other control structures is fine, since it is constrained to local use only.

Re: Goto (2007)

#70
post #54

Earlier quoted context omitted.

A function that allocates resources in several steps jumps, on error, to the teardown part at the end to deallocate (in reverse order of allocation) only the resources that were allocated. The others are skipped (jumped over). It's very popular in the Linux kernel.

> only the resources that were allocated How does it know which were allocated and which were not? If you are talking about memory allocation, then you could simply deallocate all the pointers provided they were initially set to NULL. Freeing a NULL pointer is well-defined in C.

The information is in the instruction pointer. You jump to the place that deallocates the last resource that was allocated, followed by the second-to-last etc.

Also, free(NULL) is not well-defined in C, and other resource types aren't so easy to check. delete nullptr in C++ is well-defined, but you rarely need it.

Post reply on HN