On Tue, Dec 1, 2020 at 3:40 PM Bakul Shah <bakul@iitbombay.org> wrote:
On Dec 1, 2020, at 12:20 PM, Steffen Nurpmeso <steffen@sdaoden.eu> wrote:
> Never without my goto:, and if it is only to break to error
> handling and/or staged destruction of local variables after
> initialization failures.  Traumatic school impression, finding
> yourself locked in some PASCAL if condition, and no way to go to.

Pascal had goto.

Pascal also had to go. (Thanks...I'm here all week.)

You can even do a non-local goto!

In Go you don't need goto for the sort of thing you and McVoy
talked about due to its defer statement and GC. Now granted
GC may be too big of a hammer for C/C++ but a future C/C++
add defer gainfully as the defer pattern is pretty common.
For example, mutex lock and unlock.

C++ has had something analogous for some time: destructors that run when an object goes out of scope. Scope guards to do things like close files and auto-release locks on exiting a critical section are pretty common in that world, and in general, preferable to many of the alternatives (either deeply nested conditionals or banks of labels and `goto fail1;` `goto fail2;` etc, that successively release resources on return; the latter is basically hand-rolling what the language does automatically for you, and has been the cause of at least security-related bug: apple's "goto fail" bug in their SSL implementation).

There's still no easy way to break out of nested loops, though.

But I have mixed feelings about goto vs continue/break. A nested
loop with multiple continue/break can be as obscure.

I submit that it's in how you write it: if the set of conditions on which one would break/continue are explicit and early in the loop body, it can be a very expressive way to write something. But like any tool, it can be abused.

Along those lines, it's always been interesting to me the way that Dijkstra's statement about goto must have influenced language design. The original "GOTO Statement Considered Harmful" note was quite damning, but I wonder if it meant to be: it strikes me that the really dangerous thing about "goto" isn't its mere existence or even its use, but rather, it's unconstrained use when better alternatives exist in the language. As one can observe in well-written C code, judicious use of `goto` can be quite elegant in comparison to the alternative.

I've often wondered whether  language designers, mindful of the pitfalls of `goto`, eventually took the most useful patterns of its usage and extracted them to stand on their own. Early returns from functions are an obvious example, but so are `break` and `continue` and one might argue exceptions fall into the same category. It strikes me that as we gain ever greater experience with languages, we find more and more examples of things one routinely does using a blunt instrument like goto, and we refine those to first-class features of the language.

I think it's also illustrative of how social pressure can influence one to avoid "dangerous" patterns in favor of these language features. C isn't inherently more dangerous because it has a goto statement and labels; most of the time, one doesn't bother to use goto because alternatives exist that are more natural and fill the same role (continue, break, return, etc).

        - Dan C.