I found this paragraph interesting in hindsight, 18 years on from when this discussion occurred:
> We keep lowering the bar for technical prowess, it seems; if something has the potential to be used "wrong", high-minded designers remove the offending syntax rather than find or train competent programmers. This is why Java removes pointers (among other things) -- it's not that pointers aren't useful or efficient, it's that they require discipline from programmers.
It turns out that "discipline doesn't scale", and programmers have not been able to write substantial amounts of reliable and secure software using pointers. Not Linus, not the BSD maintainers, not the OpenSSL team, not anyone. Not even with C++20 and a tool bag full of fuzzers and linters.
Meanwhile, huge amounts of quite safe Java and C# code keep happily ticking along -- exposed to the internet -- often needing patches only for the C/C++ modules that they include as a part of some framework!
One thing I've learned in my old age is that speed limits aren't there for you. They're there for the bad drivers. If you raise the speed limit, more accidents will happen, even if you can handle the speed. More accidents will happen to you, even if you never personally crash your car. Other people can hit you! https://youtu.be/a9UFyNy-rw4?t=179
In the same way, we programmers don't exist in a vacuum. We use vastly more code written by other people than we have written ourselves. Even Linus has personally touched less than 1% of the code it takes to start up a web browser on Linux and load a web page from a Linux web server. See the "30 million line problem": https://caseymuratori.com/blog_0031
To summarise: I've learned that the ecosystem matters, and that we have to optimise for the average case, because that's where the majority are in a Bell curve.
This thread isn't about safety though. It's about readability (spaghetti code). IMHO gotos in C when used for for dealing with errors at the end of the function make the code clearer.
I get that, but the comment was specifically about pointers (not gotos or structure), and is interesting in general from a historical perspective.
The "goto" keyword is similarly dangerous. I've seen very good arguments for leaving it out, and generally poor arguments for keeping it in a language. "I can use it safely" is not a good argument, because it's just like Jim Jefferies' standup routine linked above: "Why should I have my guns taken away from me?"
An example of a good argument for structured programming is the talk "The Forgotten Art of Structured Programming - Kevlin Henney [C++ on Sea 2019]": https://www.youtube.com/watch?v=SFv8Wm2HdNM
Similarly, this article makes a very good argument that concurrent or async code is essentially the "goto spaghetti reinvented, but even worse", and that Structured Concurrency is the solution: https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
Rust could comparatively easily implement goto, and it’d be unconditionally safe (as regards memory safety). I’d even honestly like it to, mostly just because it’s possible rather than because it’d be useful—most prominent goto patterns can be expressed better in other ways in Rust, e.g. RAII (destructors) instead of goto cleanup, and break/continue let you emulate any structured uses of goto. (I live in hope that https://github.com/rust-lang/rust/issues/48594 will one day land, so you can use break to skip the remainder of a labelled block, no loop required.)
I don’t think I’d want continue to work on a block. Repeating the block seems different from leaving the block early (which can already be done with return or with panicking). I think it’s better to need to write it as a loop before you can continue.
I completely agree, In rust looping has important semantics with regards to lifetimes and ownership so the continue part would be a bad idea. I think it would be cool in something like javascript (if blocks could return values...)
Read the articles I linked. This is essentially impossible, because Rust has gained features that C doesn't have by giving up goto. Adding goto back in would require those features to be removed, or to be watered down dramatically.
You wouldn't be able to goto into or out of most (all?) blocks that would change ownership, for example.
That's not that much different than C. C's goto is already limited compared to the actual jump instruction because you can't cross function boundaries because of the restrictions C puts on you.
No, not impossible at all; it will just reject any that would be memory-unsafe due to problems with borrow lengths, potentially undefined variables, and things like that. I never said you could goto absolutely anywhere; plenty of gotos are patently unsafe, and Rust would duly reject them.
Rust currently checks borrows using control-flow graphs (though I believe the plan is for that to change, and the replacement might make life harder for implementing goto, I don’t know). Rust’s mid-level intermediate representation (MIR) actually has goto. In a control-flow graph, goto is just adding new edges, and it’s comparatively simple to make it work.
You haven't mentioned anything specific about dangerousness of goto. The fact that you heard some conclusion is irrelevant, unless you pass the reasoning behind it. If goto is dangerous, why isn't if statement dangerous.
And about async code: Have fun writing bare metal code with that. Because, you know, your compiler will spit gotos anyway, and unlike gotos you write, you'll have little control over that.
Basically all modern programming control flow paradigms are about finding all the safe patterns of goto and setjmp.
Everyone agrees about loops, try catch for goto err; is near ubiquitous, defer and context managers are popular for goto cleanup;, throw is setjmp up the stack, coroutines are setjmp for multitasking.
Discipline can scale, but only among very smart and careful programmers. If you're going to have a one-size-fits-all standard that expects to include novice programmers, it can't include anything dangerous.
Even smart and careful programmers make mistakes, though, and they don't use goto for laughs. Likewise, even a novice programmer can probably use it safely in a small function.
> It turns out that "discipline doesn't scale", and programmers have not been able to write substantial amounts of reliable and secure software using pointers. Not Linus, not the BSD maintainers, not the OpenSSL team, not anyone. Not even with C++20 and a tool bag full of fuzzers and linters.
Well, Google has 100s of millions of lines of C++ that power much of the internet. They certainly have no intention of getting rid of this code, and have deemed the tradeoff worthwhile. Yes, in theory this C++ codebase might not be the most reliable or secure, but their practices are certainly scalable and battle tested. Not saying it is easy, but it is certainly possible to build an ecosystem around C++ with fuzzers/linters/whatever to reach an "acceptable" level in practice.
> Meanwhile, huge amounts of quite safe Java and C# code keep happily ticking along -- exposed to the internet -- often needing patches only for the C/C++ modules that they include as a part of some framework!
Not necessarily. Plenty of null pointer exceptions in production Java code that bring down systems. Yes, they are "safe" but I don't think the tens of millions of customers affected appreciate such subtle nuances: the consequences are the same for them.
I agree that there can be more severe consequences due to the lack of "safety" from exploits, privilege escalation, and what not. But with stuff like sandboxing, the broader ecosystem, etc the decision isn't as simple as your argument might suggest.
That is exactly the reason why Google is pushing for wide adoption of hardware memory tagging as the ultimate solution to fix that C and C++ code, because the dead corpses from battle testing have proven it is not enough.
So they definitely know how much money it costs them to keep C and C++ around, and are taking actions to reduce that monetary cost related to fixing security bugs.
On the other hand, they just introduced the Android Game Development Kit, with C and C++ APIs.
"discipline doesn't scale" is precisely why I think Robert Martin is missing the point with most of his ideology. His solution to everything seems to be "more discipline", but things don't work that way. I also find this incredibly short-sighted in an industry that can so easily build tools. Why be disciplined about formatting when you can build an autoformatter?
I don't want to use the phrase "can permit". Rust and C# have escape hatches, like the "unsafe" keyword. You can write pointer-based code in C#, but the language actively discourages it. The "happy path" is safe code. If you poke through the standard library, you'll notice that there's quite a bit of pointer arithmetic going on, either for interop or performance. On average though, 99.99% of C# code that has been written is safe[1], which is why total beginners can write an ASP.NET website, put it on the Internet, and not get hacked.
The problem with languages like C and C++ is that that the "happy path" is unsafe, unstructured, or an unexpected footgun. There's article after article written about how compilers do bizarre optimisations based on undefined behaviour.
Everyone writing a significant volume of C code is writing code littered with gotos, because as Linus said, it's the only terse way to handle error conditions in C. In C#, Java, and Rust there are structured and safe ways to handle errors (exceptions and the '?' operator). No need for liberally sprinkling code with goto.
Linus rightly makes the claim that "nothing is as good as C" at performance, or low-level control. In the past, this was entirely correct. But these days, even high-level VM-based languages like C# are acquiring features that give C++ a run for its money, and Rust is very close to C++ in performance but much safer.
[1] Memory safe at least. Most C# code is also unlikely to leak resources, unlike most C/C++ code.
The humble goto is highly efficient. There is no software of any significance that doesn't use them. Even if the programmer doesn't use them, the compiler will.
At the lowest, most efficient level of computer code, it is about the only way to create a loop.
All that being said, I wouldn't recommend it for routine use when easier, more readable alternatives are available.
I had a teammate state that Gates at the beginning of functions were also spaghetti code. E.g: If <condition>: return.
My teammate had learned that rule. from his CS teacher.
I use Gates regularly as they reduce the need for indentation which I believe is a much bigger spaghetti problem. Nothing worse than debugging 7 levels deep of indentation on a function with many pages of code. I also use Goto if the language supports them and it makes the code easier to grok.
But hey, I'm self taught with no College CS degree so what do I know ;)
ReSharper for C# discourages nesting and favours early returns instead. Having personally had the displeasure of working with code that does the opposite, I have to agree that it's the better option.
I actually agree with your teammate (moreso than you, anyway). You now have a single entry point with multiple exit points in your code, which is clearly halfway to spaghetti (even if you think it's warranted).
Your gripe is about indentation being too much to bear, which is a pretty superficial thing to complain about, and it's not even clear what your complaint about it is/why it's actually bad. It's just indentation... you can live with that imperfection on your code. It's not the end of the world. I know I'm a pretty happy developer whenever I can reduce other problems to mere indentation (which I can, explained below).
To me, every level of indentation actually conveys useful information: it tells me "hey, here's yet another precondition for this line of code", and crucially, it tells me that information at that line, without me having to keep scrolling up the function and then mentally negating the early-return condition to figure out what the precondition is. That's incredibly useful on its own. So many fixes & simplifications result from merely noticing "hey, this function has 3 preconditions, but I thought it should only have 2... what's going on?" And yet that's not all.
Beyond that: Not having early returns means there's a single entry and exit point for each procedure. That is also incredibly valuable in its own right. Try adding a simple print()/log() statement before the function returns when you have like 6 early returns in the function. At best, you remember to do it, but it's a ton of duplicated (and bloated) code, and your maintenance work just got 6x harder, and you have to keep them all in sync as the code grows (so it's greater than 6x harder). At worst you just miss half of them (or someone who adds another early return forgets to do any final steps beforehand) and now you introduce a bug. And on top of all that, it's so painful to leave a breakpoint and then realize a while later that it wasn't getting hit in every situation you expected, because there was an early return in the function that you didn't notice.
I could go on, but all this because there's "nothing worse" than some extra indentation?
Early return makes it easy to reason that the rest of the code in the function is unrelated to whatever you're checking for right now. Having multiple exit points in a function is not the end the world.
If you need to print()/log() before return, then just replace them with goto (if your language supports it). After debugging if you have no more use for print()/log() statements you can remove just those statements and keep goto as it is.
I think it's situation specific as the effect of adding another layer of indentation compounds.
That said, if either the indentation is too deep or there are more than one or two guards at the top it's probably a sign that the method should be broken out either way.
Gates at the beginning of functions are the pre-conditions in design by contract, so it tells quite a bit about that CS professor, him calling them spaghetti code.
Scott Robert Ladd gives the best reply in this thread. "GOTO considered harmful" was written in a time when you'd walk to school uphill, both ways. GOTO would let you jump anywhere, not just some label within a procedure. Procedures themselves having been invented the previous winter. Many programmers were still doing things the "old fashioned way" and academics like Dijkstra couldn't help but hold their nose looking at such code.
I do like the guy's style for getting a muted response from Linus. "Linus, I'm a newbie but I disagree with you about X." then "Linus, you're a successful guy by Y."
Usually folks who got shouted at use the collision course with Linus so kudos to this chap for seeing how to frame the questions :)
OT: I knew that the Edsger Dijkstra's letter "Go To Statement Considered Harmful" popularized the phrase in CS circles.
> [But I didn't know that] the original title of the letter, as submitted to CACM, was "A Case Against the Goto Statement", but CACM editor Niklaus Wirth changed the title to "Go To Statement Considered Harmful". Regarding this new title, Donald Knuth quipped that "Dr. Goto cheerfully complained that he was always being eliminated."
> [Dr. Goto is referring to] Eiichi Goto (後藤英一, Gotō Eiichi, January 26, 1931 – June 12, 2005) was a Japanese computer scientist, the builder of one of the first general-purpose computers in Japan.
> As a final argument, it does not let us cleanly do the usual stack-esque
wind and unwind, i.e.
do A
if (error)
goto out_a;
do B
if (error)
goto out_b;
do C
if (error)
goto out_c;
goto out;
out_c:
undo C
out_b:
undo B:
out_a:
undo A
out:
return ret;
That's pretty neat when you lack a try-finally control structure in the language.
Here's a strong suggestion to anyone thinking "goto -> automatically bad". Before you rag on that lonely goto that is used for clearly structured error reporting in some C-source, go and find some actual source that was written before structured programming became a thing. The problem those people had wasn't that single goto; it was the random jumping all over the place that was used for all forms of flow control. If you haven't seen that you cannot imagine what it was like. Today's sad little goto offers no danger whatsoever in the few places where it's still being used, and we should really stop hammering on about it when it has been dead and buried for longer than most of you have been alive.
> In most ways, the quality of Linux code equals or exceeds that of
commercial products I've worked on.
Maybe, and I know this is old but I am shocked by the blunt and rude communication.I’d prefer to work on lower quality code with people who aren’t “rude” to each other like this, saying “stop this”, “you have been brainwashed”, “ Niklaus Wirth has no friggin clue”, “language designers have brain damage”.
Most companies I have worked at have tended to value communication over technical skill, since the latter can be taught much easier.
Even if a junior engineer “rubs you wrong”, I believe senior engineers should respond with the intent to help them learn, whereas multiple people in this thread seem to be responding out of emotion. Regardless of whether the original poster has an irrational hate for goto, the senior engineers responding here have an irrational defensive and aggressive tone. I wish more engineers would learn to stop getting so worked up when opinions differ.
A much better way to handle this is “I see your point, however we disagree and would like you to please consider these counter points”
The first reply was nice, in my opinion. The reply to that reply was what may have rubbed Linus the wrong way. First, he brought up an argument that didn't apply to the code in example (where the goto jumps forward but not backwards). Then, his
> It's
just "common sense" as I've always been taught. Unless you're
intentionally trying to write code that's harder for others to read.
Note the first reply was where Linus says the creator of Pascal has “brain damage”
I agree “unless you’re intentionally trying to write code badly” reads as abrasive but the good faith interpretation is that the junior engineer doesn’t intend to accuse Linus of same, and is just awkward (or responding in kind?)
On the other hand, saying the creator of Pascal has brain damage seems intended to offend or shows a lack of respect to peers.
You’re right though that everyone showed suboptimal communication here.
Strictly microprocessors ONLY do GOTO at an assembly/machine code level. So it's merely a snobby abstraction to shun them on reflex rather than thinking the specifics through.
Well, goto in this case is not that bad. Without goto the Linux code would be full of many nested if-else, what would lead to more bugs, as C lacks C++ RAAI (Resource-Acquisition-Is-Initialization) feature that allows usage of class destructors for executing actions at the end of scope such as releasing resources and deallocating memory. Besides Linux kernel, Goto is widely used on C programming for embedded systems for error handling, managing resources and creating finite state machines. It is possible to use RAAI in C, but only with GCC proprietary features that will make the code non portable to other C compilers.
55 comments
[ 2.3 ms ] story [ 34.6 ms ] thread> We keep lowering the bar for technical prowess, it seems; if something has the potential to be used "wrong", high-minded designers remove the offending syntax rather than find or train competent programmers. This is why Java removes pointers (among other things) -- it's not that pointers aren't useful or efficient, it's that they require discipline from programmers.
It turns out that "discipline doesn't scale", and programmers have not been able to write substantial amounts of reliable and secure software using pointers. Not Linus, not the BSD maintainers, not the OpenSSL team, not anyone. Not even with C++20 and a tool bag full of fuzzers and linters.
Meanwhile, huge amounts of quite safe Java and C# code keep happily ticking along -- exposed to the internet -- often needing patches only for the C/C++ modules that they include as a part of some framework!
One thing I've learned in my old age is that speed limits aren't there for you. They're there for the bad drivers. If you raise the speed limit, more accidents will happen, even if you can handle the speed. More accidents will happen to you, even if you never personally crash your car. Other people can hit you! https://youtu.be/a9UFyNy-rw4?t=179
In the same way, we programmers don't exist in a vacuum. We use vastly more code written by other people than we have written ourselves. Even Linus has personally touched less than 1% of the code it takes to start up a web browser on Linux and load a web page from a Linux web server. See the "30 million line problem": https://caseymuratori.com/blog_0031
To summarise: I've learned that the ecosystem matters, and that we have to optimise for the average case, because that's where the majority are in a Bell curve.
The "goto" keyword is similarly dangerous. I've seen very good arguments for leaving it out, and generally poor arguments for keeping it in a language. "I can use it safely" is not a good argument, because it's just like Jim Jefferies' standup routine linked above: "Why should I have my guns taken away from me?"
An example of a good argument for structured programming is the talk "The Forgotten Art of Structured Programming - Kevlin Henney [C++ on Sea 2019]": https://www.youtube.com/watch?v=SFv8Wm2HdNM
Similarly, this article makes a very good argument that concurrent or async code is essentially the "goto spaghetti reinvented, but even worse", and that Structured Concurrency is the solution: https://vorpus.org/blog/notes-on-structured-concurrency-or-g...
Rust could comparatively easily implement goto, and it’d be unconditionally safe (as regards memory safety). I’d even honestly like it to, mostly just because it’s possible rather than because it’d be useful—most prominent goto patterns can be expressed better in other ways in Rust, e.g. RAII (destructors) instead of goto cleanup, and break/continue let you emulate any structured uses of goto. (I live in hope that https://github.com/rust-lang/rust/issues/48594 will one day land, so you can use break to skip the remainder of a labelled block, no loop required.)
You wouldn't be able to goto into or out of most (all?) blocks that would change ownership, for example.
Rust currently checks borrows using control-flow graphs (though I believe the plan is for that to change, and the replacement might make life harder for implementing goto, I don’t know). Rust’s mid-level intermediate representation (MIR) actually has goto. In a control-flow graph, goto is just adding new edges, and it’s comparatively simple to make it work.
And about async code: Have fun writing bare metal code with that. Because, you know, your compiler will spit gotos anyway, and unlike gotos you write, you'll have little control over that.
Everyone agrees about loops, try catch for goto err; is near ubiquitous, defer and context managers are popular for goto cleanup;, throw is setjmp up the stack, coroutines are setjmp for multitasking.
Brilliant observation!
I can have disciplined new hires, but they don't know what they don't know yet about what is at stake.
Even smart and careful programmers make mistakes, though, and they don't use goto for laughs. Likewise, even a novice programmer can probably use it safely in a small function.
Well, Google has 100s of millions of lines of C++ that power much of the internet. They certainly have no intention of getting rid of this code, and have deemed the tradeoff worthwhile. Yes, in theory this C++ codebase might not be the most reliable or secure, but their practices are certainly scalable and battle tested. Not saying it is easy, but it is certainly possible to build an ecosystem around C++ with fuzzers/linters/whatever to reach an "acceptable" level in practice.
> Meanwhile, huge amounts of quite safe Java and C# code keep happily ticking along -- exposed to the internet -- often needing patches only for the C/C++ modules that they include as a part of some framework!
Not necessarily. Plenty of null pointer exceptions in production Java code that bring down systems. Yes, they are "safe" but I don't think the tens of millions of customers affected appreciate such subtle nuances: the consequences are the same for them.
I agree that there can be more severe consequences due to the lack of "safety" from exploits, privilege escalation, and what not. But with stuff like sandboxing, the broader ecosystem, etc the decision isn't as simple as your argument might suggest.
https://source.android.com/devices/tech/debug/tagged-pointer...
https://security.googleblog.com/2019/08/adopting-arm-memory-...
https://threatpost.com/google-arm-android-bugs-memory-taggin...
https://source.android.com/devices/tech/debug/hwasan
Google also paid for the effort to remove C99's VLAs from the Linux kernel.
https://www.phoronix.com/scan.php?page=news_item&px=Linux-Ki...
Google is also the company that started the effort to adopt Rust in the Linux kernel.
https://security.googleblog.com/2021/04/rust-in-linux-kernel...
So they definitely know how much money it costs them to keep C and C++ around, and are taking actions to reduce that monetary cost related to fixing security bugs.
On the other hand, they just introduced the Android Game Development Kit, with C and C++ APIs.
https://developer.android.com/games/agdk
The problem with languages like C and C++ is that that the "happy path" is unsafe, unstructured, or an unexpected footgun. There's article after article written about how compilers do bizarre optimisations based on undefined behaviour.
Everyone writing a significant volume of C code is writing code littered with gotos, because as Linus said, it's the only terse way to handle error conditions in C. In C#, Java, and Rust there are structured and safe ways to handle errors (exceptions and the '?' operator). No need for liberally sprinkling code with goto.
Linus rightly makes the claim that "nothing is as good as C" at performance, or low-level control. In the past, this was entirely correct. But these days, even high-level VM-based languages like C# are acquiring features that give C++ a run for its money, and Rust is very close to C++ in performance but much safer.
[1] Memory safe at least. Most C# code is also unlikely to leak resources, unlike most C/C++ code.
At the lowest, most efficient level of computer code, it is about the only way to create a loop.
All that being said, I wouldn't recommend it for routine use when easier, more readable alternatives are available.
"You're a relatively succesful guy, so I guess I shouldn't argue with your style."
My teammate had learned that rule. from his CS teacher.
I use Gates regularly as they reduce the need for indentation which I believe is a much bigger spaghetti problem. Nothing worse than debugging 7 levels deep of indentation on a function with many pages of code. I also use Goto if the language supports them and it makes the code easier to grok.
But hey, I'm self taught with no College CS degree so what do I know ;)
I've heard second-hand about places which follow that guideline. I'm against it, for reasons you and others say.
BTW, those are usually called "guards", not "Gates". https://en.wikipedia.org/wiki/Guard_(computer_science) .
Your gripe is about indentation being too much to bear, which is a pretty superficial thing to complain about, and it's not even clear what your complaint about it is/why it's actually bad. It's just indentation... you can live with that imperfection on your code. It's not the end of the world. I know I'm a pretty happy developer whenever I can reduce other problems to mere indentation (which I can, explained below).
To me, every level of indentation actually conveys useful information: it tells me "hey, here's yet another precondition for this line of code", and crucially, it tells me that information at that line, without me having to keep scrolling up the function and then mentally negating the early-return condition to figure out what the precondition is. That's incredibly useful on its own. So many fixes & simplifications result from merely noticing "hey, this function has 3 preconditions, but I thought it should only have 2... what's going on?" And yet that's not all.
Beyond that: Not having early returns means there's a single entry and exit point for each procedure. That is also incredibly valuable in its own right. Try adding a simple print()/log() statement before the function returns when you have like 6 early returns in the function. At best, you remember to do it, but it's a ton of duplicated (and bloated) code, and your maintenance work just got 6x harder, and you have to keep them all in sync as the code grows (so it's greater than 6x harder). At worst you just miss half of them (or someone who adds another early return forgets to do any final steps beforehand) and now you introduce a bug. And on top of all that, it's so painful to leave a breakpoint and then realize a while later that it wasn't getting hit in every situation you expected, because there was an early return in the function that you didn't notice.
I could go on, but all this because there's "nothing worse" than some extra indentation?
If you need to print()/log() before return, then just replace them with goto (if your language supports it). After debugging if you have no more use for print()/log() statements you can remove just those statements and keep goto as it is.
That said, if either the indentation is too deep or there are more than one or two guards at the top it's probably a sign that the method should be broken out either way.
'fail fast'
Maybe something you would like to dive into,
https://en.wikipedia.org/wiki/Design_by_contract
loops and functions are compiled down to goto (or jump). Everyone uses them behind higher level structures.
pure goto is indispensably useful for error handling in C.
Usually folks who got shouted at use the collision course with Linus so kudos to this chap for seeing how to frame the questions :)
> [But I didn't know that] the original title of the letter, as submitted to CACM, was "A Case Against the Goto Statement", but CACM editor Niklaus Wirth changed the title to "Go To Statement Considered Harmful". Regarding this new title, Donald Knuth quipped that "Dr. Goto cheerfully complained that he was always being eliminated."
> [Dr. Goto is referring to] Eiichi Goto (後藤英一, Gotō Eiichi, January 26, 1931 – June 12, 2005) was a Japanese computer scientist, the builder of one of the first general-purpose computers in Japan.
[0] https://en.wikipedia.org/wiki/Considered_harmful
Maybe, and I know this is old but I am shocked by the blunt and rude communication.I’d prefer to work on lower quality code with people who aren’t “rude” to each other like this, saying “stop this”, “you have been brainwashed”, “ Niklaus Wirth has no friggin clue”, “language designers have brain damage”.
Most companies I have worked at have tended to value communication over technical skill, since the latter can be taught much easier.
Even if a junior engineer “rubs you wrong”, I believe senior engineers should respond with the intent to help them learn, whereas multiple people in this thread seem to be responding out of emotion. Regardless of whether the original poster has an irrational hate for goto, the senior engineers responding here have an irrational defensive and aggressive tone. I wish more engineers would learn to stop getting so worked up when opinions differ.
A much better way to handle this is “I see your point, however we disagree and would like you to please consider these counter points”
> It's just "common sense" as I've always been taught. Unless you're intentionally trying to write code that's harder for others to read.
comes off as condescending.
I agree “unless you’re intentionally trying to write code badly” reads as abrasive but the good faith interpretation is that the junior engineer doesn’t intend to accuse Linus of same, and is just awkward (or responding in kind?)
On the other hand, saying the creator of Pascal has brain damage seems intended to offend or shows a lack of respect to peers.
You’re right though that everyone showed suboptimal communication here.
In this article John Rehger makes the case for GOTO - https://blog.regehr.org/archives/894.