6 ms·
I've always defended goto and gotten a lot of flak for it. As soon as I say, "I wish I had X-language had gotos", I see jaws drop. Response: "Wow, haven't you h
by chjj 11y ago
I've always defended goto and gotten a lot of flak for it. As soon as I say, "I wish I had X-language had gotos", I see jaws drop. Response: "Wow, haven't you heard the news?! GOTOs are considered harmful!"
I think goto should be in almost every language. It's one of the most primitive instructions, why shouldn't it be available when needed? Yes, it can be misused, just like any other feature in the language, but it can also be used to great benefit. State machines, for example, can make good use of gotos.
Hell, look at any unix library your machine uses every day. The ones you don't even think about. Start with libncurses: I promise there's a few gotos where needed.
$ find ~/ncurses-5.9 -name '*.c' -print0 | xargs -0 grep goto | wc -l
70
Raise your hand if you plan to stop using ncurses because of how opposed to how "harmful" goto statements are.
Oh, here's tmux, if you're interested (one of the most beautifully written C programs): https://github.com/tmux/tmux/search?utf8=%E2%9C%93&q=goto https://github.com/tmux/tmux/search?utf8=%E2%9C%93&q=goto
- jxf 11y ago> It's one of the most primitive instructions, why shouldn't it be available when needed? I see what you're saying, though I don't find this a compelling argument. By this logic, why not allow direct register access in all languages? Just because something is a primitive operation doesn't mean you want to include it, especially not if it's more difficult to enforce guarantees your language would like to make about valid programs.
- MaulingMonkey 11y ago> Raise your hand if you plan to stop using ncurses because of how opposed to how "harmful" goto statements are. What if I just avoid contributing to the ncurses codebase? I've used plenty of useful tools with absolutely horrific codebases that I'd never want to touch in a million years. Not sure if ncurses is one of them. The whole "it gets used, ergo it must be a good idea" argument doesn't hold much traction with me - even if I think using it when in C, to enforce single exit style, to work around the lack of RAII constructs, goto is the lesser evil. I started with GOTO in BASIC. I used it a lot. It structured my initial reasoning about control flow. Despite this, in the past few years, I've used a naked goto maybe once or twice, and in all cases later rewrote it without the goto, which in my opinion increased it's readability. (I generally always have the option of C++ over C, and choose it, rendering single exit style 'useless'.) > Oh, here's tmux, if you're interested (one of the most beautifully written C programs): https://github.com/tmux/tmux/search?utf8=%E2%9C%93&q=goto https://github.com/tmux/tmux/search?utf8=%E2%9C%93&q=goto Most of those are single exit style gotos. Those that aren't, do cause some concern, despite being "one of the most beautifully written C programs", even to their original author from the looks of it: if (errno == ENOMEM) goto retry; /* possible infinite loop? */ For what it's worth, it seems unlikely to be an infinite loop, short of encountering a bug in sysctl, or another process/thread constantly adding data. I had to google the header path to find an appropriate manpage (i.e. not _sysctl, not sysctl the program) to figure this out... I've encountered worse edge cases before, however, and I'd really prefer my programs crash properly, instead of hanging when they do. > State machines, for example, can make good use of gotos. The performance complaints about an additional branch misprediction when using the "for(;;) switch(...)" style without gotos, is one of the few arguments that moves me, if only slightly. That seems like a case your standard optimizing compiler really should be able to handle, however. I'll assume they don't, as I'm too lazy to test if this is merely hearsay... That said, I'll even use "goto case" in C# on occasion where I'd use case fallthrough in C++, if I'm feeling particularly lazy and don't want to turn things into proper method calls that can simply call each other just yet. I usually clean it up before I start to confuse myself. It's not something I'd miss if it were gone, however. It's something I use only rarely, and only as a crutch to stave off cleanup. Not exactly a ringing endorsement. EDIT: Code formatting, proper insertion of subject...
- pcwalton 11y agoAll of the gotos I see on that page are simulations of RAII or labeled break/continue.
- istvan__ 11y agoI do not use goto in my code. What do I do wrong? :) Ok, I have to admit that I used it on C64 in the 80s. Anyways, exceptions are sort of gotos or at least they can behave that way.
- EugeneOZ 11y agoNo, exceptions are incomparable much harmful because they don't have destination, they just hysterically run, crashing everything on their way.
- istvan__ 11y agoI said "sort of"...
- sklogic 11y agoIf you're not implementing fast FSMs, fast bytecode interpreters (and dynamic dispatchers in general), and you're not using metaprogrming to the full power, not implementing multiple embedded DSLs - then you can live without a goto. Otherwise it is essential.
- pjmlp 11y agoMetaprogramming to the full power sounds like Lisp. It doesn't have goto.
- sklogic 11y ago> Metaprogramming to the full power sounds like Lisp. It does, yes, although many Lisps got a pretty limited backend for this sort of things. My preferred metaprogramming environment must have a fallthrough mode for allowing generating low-level code where Lisp semantics is not sufficient. Rust seems like a very good target platform in this sense, so the lack of goto really hurts. > It doesn't have goto. Of course they do (tagbody in Common Lisp, for example). And when they don't, it's often relatively easy to add one.
- geofft 11y agoRust is not a language that looks favorably on things that are easy to misuse and hard to use correctly. You can make the same argument about, say, untagged / C-style unions, which are much more common in C, but Rust doesn't have those either. I don't plan to stop using ncurses in particular, but one of the reasons I am supportive of Rust is that I would like to stop using all C software sometime in my lifetime.
- milspec 11y agoRust should have untagged unions. Obviously, ones that allow pointer abuse would be restricted to code marked unsafe. Note that a union of two pointer-containing structs is safe as long as the pointers line up, having the same type and offset in each struct.
- jroesch 11y agoDo you have a compelling use case? I can't imagine a use for untagged unions in Rust that isn't subsumed by other features in the language.
- mbrubeck 11y agoThe most common use case would be interop with C libraries that use untagged unions. This is a significant hassle when writing C bindings in Rust today.
- Jweb_Guru 11y agoI can think of many, mostly revolving around cases where the tag is not stored inline with the structure in question. Where space efficiency is important this is quite common. C interoperability is obviously another important use case (the current solution of passing around [u8] arrays is pretty atrocious).
- comex 11y agoThey've been proposed: https://github.com/rust-lang/rfcs/pull/724 https://github.com/rust-lang/rfcs/pull/724 If you really need them, you can implement them in a library by declaring a suitably sized byte array and having methods that return casted pointers to it. This would be illegal in C due to strict aliasing, but IIRC Rust does not have a strict aliasing rule (because almost all pointers being the equivalent of 'restrict' drastically reduces the benefit). There are issues with size_of not being a constant expression and such (at least in stable), but those are definitely going to be fixed.
- mercurial 11y agoThe kernel has plenty of goto, mostly (as far as I know) to handle errors and safe resource deallocation. There is no reason to keep using GOTO if you have better mechanisms to handle these things.
- adynatos 11y agoC's goto has a bad rep it only partially deserves, however I can't agree that it should be in every language. I use it fairly frequently, but virtually all the uses are about cleanup after error. I like that it requires unique label for identification, as it allows for language-enforced documentation. But my gotos always go "down" the source code, never "up. Through goto I can basically setup an error-condition code flow for every function, with multiple conditional entry points into that flow and if there was another language feature that allowed just this particular usage in cleanup, without multiple nested scopes and with clear labelling, then I would see no reason for keeping goto. Throughout the years we developed a way to neatly use an unsafe feature, but it's always better to have such things enforced by language, not by tradition.
- Retra 11y agoThe target of a goto statement is a specific place in code. It is not code that refers to the task you are trying to perform. The main advantage of using higher-level languages is that you can talk about manipulations of data. Goto doesn't manipulate data, it manipulates the machine. And if you want to _really_ manipulate the machine, you're going to want more than just goto. >Raise your hand if you plan to stop using ncurses because of how opposed to how "harmful" goto statements are. Goto statements are not harmful to computers or to code. Ncurses isn't what is harmed by goto, nor does "using ncurses" imply any interaction with goto at all. Muhammad Ali was a good boxer. He was Muslim. Am I to conclude that one must be Muslim to be a good boxer, now? Yes, ncurses is a good program. Yes it uses goto. But that doesn't imply that goto is necessary to it being a good program. Or that it is even a mildy efficient way of doing well. (Especially not when there is a whole universe of alternatives.) If you're going to defend goto (and there are reasons to do this) you should probably do so without employing such blatant logical fallacies. It's irresponsible and detracts from your point.