Settings

Theme

If goto statements are bad why does linux src have more than 10k of them?

github.com

31 points by ilovecookies 11 years ago · 47 comments

Reader

jandrewrogers 11 years ago

Contrary to popular reputation, there are a handful of use cases where "goto" makes the code simpler, cleaner, more readable, and (in rarer cases) faster. In these cases, you should use goto statements. A good programmer can recognize these cases and use goto appropriately. Goto is never necessary in a strict sense but occasionally it can eliminate some pretty ugly spaghetti code.

The use cases for goto I see are primarily complex/thorough error handling (e.g. unwinding some concurrency control mechanisms) and certain low-level state machine patterns. I would expect to see these kinds of use cases in the Linux kernel.

  • wcummings 11 years ago

    And C doesn't have exceptions, which otherwise would cover a lot of where goto's are used.

    • shortsightedsid 11 years ago

      There is a difference though. Exceptions can result in Stack Unwinding which is costly. Gotos are a jump which costs literally nothing.

      • asveikau 11 years ago

        In practice you will do the same thing as unwinding the stack. You'll jump to the end of a function where you'll likely free some heap buffers on your way out and you'll return error status to the caller. What will likely happen next is the caller will bubble up the error: free buffers and report error status to their caller. It works out to pretty much the same thing as a modern C++ code base using RAII, just more manual.

    • tormeh 11 years ago

      It does have longjmp, which can do basically the same, just without safety (surprise!)

  • ilovecookiesOP 11 years ago

    Seems like they use it for most of the error handling, that's true. Almost as many of these as there are switch statements (and 1/3 of if statements). It would be cool if someone could analyze keywords from different projects. Maybe one could give that as use cases in universites instead, that would seem to be alot more practical.

    EDIT: Upon closer inspection it seems like even if 'gotos' make everything nastier the extra added performance is worth it.

  • agumonkey 11 years ago

    As long as they're local I guess, like a handmade `finally` clause. It's like mutation in functional programming languages, they're allowed as long as they don't leak. IIRC Zed Shaw's Learn C the Hard Way has some nice `goto` examples..

  • zzzcpan 11 years ago

    Breaking from nested loops with goto is also cleaner and simpler. Which is actually one of the reasons some higher level languages even have a goto statement.

    • _delirium 11 years ago

      For that use-case in particular, a "labeled break" is an alternative that some languages use (like java). I somewhat semantically prefer it if given the choice (name the loop being broken, vs. naming the end-point to jump to), though that preference isn't strong.

  • dmux 11 years ago

    Ah yes, the "good" programmer that is well versed in when goto statements are warranted.

estebank 11 years ago

The original context of the "GOTO considered harmful" is lost on most of us, as at the time there were large swaths of developers that were trained before structured programming took off, so people were using global variables and GOTOs instead of procedures and functions. GOTO has its place, specially in C.

It is sinful to jump into a different function and pass around information as global state. GOTO as functionality is tangential in this matter.

  • danellis 11 years ago

    Growing up in the 80s, that's how a lot of books taught us BASIC, because they catered to a lowest-common-denominator implementation. Fortunately, I was using BBC BASIC, with functions, procedures and REPEAT-UNTIL (and later WHILE and CASE), and the BBC-specific books taught structured programming.

  • asveikau 11 years ago

    > It is sinful to jump into a different function

    I've heard of that. It's called "exceptions", right?

    I find it kind of amusing when people are afraid of "goto" but not "throw", "break" or "return".

    • lukeschlather 11 years ago

      You skipped the "and pass information around as global state" part. It obviously depends on your language, but ideally an Exception object should be a specific class you can choose to catch or re-raise, and it should include a message. None of the calling state should be visible to you.

      • asveikau 11 years ago

        I give you that I skipped it. I skipped it intentionally to make a bit of hyperbole.

        An exception is still essentially a goto that crosses stack frames. There is a whole class of common bugs, you will see a lot of talk of them in the C and C++ communities, where an early return or a throw at an unexpected time leads to resources not being cleaned up. A lot of good coding styles say avoid this stuff, it's dangerous, and they are not without cause. Whereas a goto cleanup block is often a lot more explicit and therefore can lead to more reliable code than a scheme that encourages not sweating details and not expecting failure at every step.

  • wcummings 11 years ago

    >It is sinful to jump into a different function

    So sinful you can't in C

    • astrange 11 years ago

      You can do it in GNU C! It's used to write direct-threading interpreters.

      https://gcc.gnu.org/onlinedocs/gcc-3.1/gcc/Labels-as-Values....

      • knome 11 years ago

        They don't intend for label addresses to be gone to outside of the function they are located in. The stack wouldn't be setup to handle them at all.

        Sure, you can store them wherever, and do something like " goto *g_greenthreads[ threadno ].lastpos ", but you would call that within the function defining the label, not outside it.

        From your own link: > You may not use this mechanism to jump to code in a different function. If you do that, totally unpredictable things will happen. The best way to avoid this is to store the label address only in automatic variables and never pass it as an argument.

    • danudey 11 years ago

      I assumed the parent poster meant back before functionality was expressed as functions; i.e. it's sinful to jump from functionality A to functionality B if it's not expressed in terms of packaged functions, and impossible to do so if it is.

    • tormeh 11 years ago

      With longjmp you can. Your stack will be trashed, though, so any state better be global!

kristopolous 11 years ago

Dogmatically following so called rules in a cargo cult programming style without any understanding of the rationale behind them is many orders of magnitude more bad.

This form of blind programming is terribly dangerous. It takes focus away from the task and placed on the process.

Engage with the problem, engage with the computer. Do not engage with autocratic decrees and programming equivalencies of heretic and kosher.

Goto does something specific. If you need that specific thing then that's why it's there. Ceremonial rituals be damned

thomaslee 11 years ago

At a glance, looks like most of 'em are used for error handling. Sort of a `try ... finally` for C. This is actually a fairly common pattern -- check out Python's source code for more examples.

The other way I've seen it used is to break out of multiple levels of nested loops, though that's far less common.

`goto` is bad when it's used in an unstructured way: e.g. A does some stuff, then `goto B`. Then B does some stuff, then `goto C`. C sets a flag, does more stuff, then `goto B`. B does something different this time around based upon the flag set by C. Jumping around in a completely uncontrolled way such that the code can't be comprehended is where goto is "bad".

goto isn't inherently bad, it's just easy to use it in bad ways (and once upon a time, people did so more so than they generally do today -- which iirc was Dijkstra's major beef with it)

NelsonMinar 11 years ago

Linus himself has publicly said he doesn't mind appropriate gotos. "I think goto's are fine, and they are often more readable than large amounts of indentation." Mind you this was 11 years ago, and it's weird to quote him as some sort of oracle. But it seems relevant.

https://web.archive.org/web/20120331202351/http://kerneltrap...

AdmiralAsshat 11 years ago

They're usually used for an error clean-up section at the bottom.

Zed Shaw introduces some debug macros here which make use of a goto:

http://c.learncodethehardway.org/book/ex20.html

From that point on in the book, pretty much every function written has an "error:" label at the bottom where stuff gets cleaned up and memory freed. You can see his example code for it there.

Pretty useful macros, really. Context for the "goto considered harmful" always seems lost on young coders these days, unaware of the kind of spaghetti code that overuse of goto had caused.

  • kabdib 11 years ago

    Yeah, I've been on teams that have used this kind of error handling extensively, at several different companies. It's lightweight, very little is being done behind your back (do you know when your destructors are being called? really?) and it's easily inspected.

    Also, never pass up the opportunity to troll a god-fearing "goto puritan" :-)

steakejjs 11 years ago

"Goto is bad" is something that professors tell first year computer science students because as computer scientists, the students will find novel ways of abusing them.

Using goto for error cleanup is pretty standard, easily readable, and understandable.

It avoids ugly braces and depth.

So, are gotos bad? It depends.

xantronix 11 years ago

One of these days, "gotos: The Good Parts" will overshadow EWD's oft-abused essay, and the world will be spared highly nested, pointy-arrow C resource cleanup code.

10098 11 years ago

http://onlinehut.org/2011/10/goto-is-not-evil-okay/

peterkelly 11 years ago

Because they're not bad when you use them for actions which would go in a "finally" block in a language that supports exception handling.

zzzcpan 11 years ago

I think what people are trying to say is that you shouldn't be taking too seriously all these advises about good and bad features in programming languages. Instead, try to understand the reasons behind such advises. All the bad things, that goto is blamed for, can be just as easily made with a bunch of methods in some object.

CGamesPlay 11 years ago

Even C# has the goto statement. http://weblogs.asp.net/stevewellens/why-goto-still-exists-in...

beachstartup 11 years ago

without a goto, you have to rely on functions/return values/pointers, which implies a function call (sometimes billions of times), which can have performance and design implications.

imanaccount247 11 years ago

Because it is written in C. "Goto statements are bad" meant: lets start using languages that offer higher level constructs to replace the current usage of goto. Things like "loops" and "functions" and "exceptions". C did not get the memo.

  • 10098 11 years ago

    > Because it is written in C.

    Writing something in C does not automatically imply having to use goto.

    > "Goto statements are bad"

    Goto statements are not bad.

    > Things like "loops" and "functions" and "exceptions". C did not get the memo.

    C has loops and functions. Bro do you even K&R?

    It might be a good idea to know what you're going to be talking about before opening your mouth.

    • imanaccount247 11 years ago

      >Writing something in C does not automatically imply having to use goto.

      I didn't say it did. But any large enough C project will obviously use them.

      >Goto statements are not bad.

      Do you know what quotation marks are?

      >C has loops and functions

      It does not have exceptions. Which is what all the goto uses in question are being used for.

      >It might be a good idea to know what you're going to be talking about before opening your mouth.

      How ironic.

  • ninkendo 11 years ago

    C has loops and functions. But you're right that modern use of goto is typically used in error handling to replace specific use cases of exceptions in a primitive way (If error, goto end of function where cleanup is done before the return statement.)

    • imanaccount247 11 years ago

      >C has loops and functions

      Which leaves...

      > But you're right that modern use of goto is typically used in error handling to replace specific use cases of exceptions in a primitive way

      Exactly. I pointed out the context of "goto considered harmful". Obviously the one that applies to C is the one that is the reason for all the gotos in C code.

jarfil 11 years ago

GOTO statements are not bad, they make your code run 10% faster while taking just 10 times as long to debug.

So if your code gets executed millions of times per second, like in some OS kernel, it may be wise to use GOTOs.

Otherwise, stay away.

  • vardump 11 years ago

    Gotos are nowhere near as hard to debug as exceptions.

    • pontifexa 11 years ago

      How's that? To debug GOTOs you have to place breakpoints on each possible detection of error (or at a shared trampoline). To debug exceptions, you just enable first-chance exception handling for the kind of exception you're interested in and you're done.

Joky 11 years ago

This is because Linux Kernel source code is not representative of what usual software should look like. And also because C is terrible ;)

  • 10098 11 years ago

    Please get some experience writing kernel and driver code before making inane statements.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection