HACKER Q&A
📣 soheil

Why does Linux Kernel use goto statements?


I noticed this goto statement while going through the kernel code. Why is it there and isn't it an indication of bad design? https://github.com/torvalds/linux/blob/19901165d90fdca1e57c9baa0d5b4c63d15c476a/kernel/acct.c#L490


  👤 retrac Accepted Answer ✓
Not every use of goto is a sin, at least according to Linus.

How would you write it without goto? Duplicate the code at the bottom, then return? Abstract what is clearly part of that function, into a new function, pass acct to it, call it twice? Neither seems much better to me. And both lead to multiple return statements in the function, which is also considered poor style by some.

Goto common code at the end of a function, such as error handling or clean-up, is idiomatic C. Often where you'd use an exception or conditional execution, in another language. I mostly avoid it myself. Outside of that use, it's probably most common in the drivers as a way to simply implement a state machine.


👤 ThrowawayR2
> "...isn't it an indication of bad design?"

No. See https://en.wikipedia.org/wiki/Goto#Common_usage_patterns It's still used in systems programming contexts and in machine language, where there are no branching constructs other than conditional or unconditional jumps (i.e. "goto").


👤 throwaway29303

  (I _like_ using goto's every once in a while: it can often mess up the gcc optimizer just enough to get better code out of it. In this case, as the signal test is not usually true, the goto forces gcc to use better jump placement and avoid the branch in the usual case).

  As to whether it reall matters: no, it doesn't. The largest reason I do this once in a while is that I look at the assembly gcc produces for quite other reasons, and use a goto to make it slightly easier to read (not the C code, the assembly ;-)
http://lkml.iu.edu/hypermail/linux/kernel/9507/0475.html

Please note that this is from 1995. Compiler behaviour might have changed.

Other interesting posts:

https://marc.info/?l=linux-kernel&m=104240115806388&w=2

https://marc.info/?l=linux-kernel&m=104240357108566&w=2

https://marc.info/?l=linux-kernel&m=104240441009296&w=2


👤 phendrenad2
C is sometimes called "portable assembly" because it allows you to use all of the features of a CPU's ISA (but it abstracts over the differences in opcodes). This includes GOTO, which is analogous to "JMP", which is the cornerstone of digital computing. In other words, FOR and WHILE are compiled to GOTO by your compiler anyway.

The idea that using GOTO is an indication of bad design was started by Edsger Dijkstra, and I've always found it to be a black spot on his reputation. Read it for yourself, and I think you'll come to the conclusion that he has no idea what he's talking about: https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.p... He has certainly no idea in what cases GOTO might be useful, and likely has never talked to anyone who was writing an OS kernel or driver. Remember, he was primarily an algorithms researcher turned educator, so his experience of the "Go To Statement" is entirely from students turning in programs for him to grade.


👤 dusted
That's a fine use of goto and not in any way bad design in my opinion.

It makes it very clear that it's _REQUIRED_ to run the cleanup stuff regardless of the skipped block.

It does so without wrapping the entire skipped block in an IF (which also has two side effects: of causing more indentation and making the cleanup stuf look less required, or incidental).

It does so without adding another tiny silly, only-_REALLY_-used-on-place function for cleaning up, which decreases readability and causes more code duplication since there is then a need for not one, but two function calls and/or multiple return paths where not needed.


👤 kettunen
Many people tend to assume goto is bad design, and while it definitely can be, there are some great uses for it especially on low level code.

I feel like this idea of goto being bad dates back to Djikstra's essay about the subject. I think quite often people tend to reference this and based on that declare that goto is always bad while missing the point that Djikstra was actually talking about goto being harmful when proving algorithms, not necessarily in real world code where there are great use cases for it when used in moderation.


👤 CheezeIt
Even if it were suboptimal in that usage (but it looks like the best choice to me), the extent of the harm would be contained to the function body. Nothing outside could “see” that a goto was used.

If you worsened the function, such as by duplicating the cleanup code and using a return statement, that would be worse, and unacceptable, but still, the harm would be contained to the function body.


👤 wmf
This is the C equivalent of a try {...} finally {...} block and the Linux coding style allows it because it makes code cleaner.

👤 iExploder
some of possible reasons to use goto:

1. escape nested loops easily

  for ()
    ...
    for()
      ...
      if (something)
         goto get_me_out
      ...

  get_me_out:
2. error handling; since c does it in somehow messy way, you can end up with multiple variations of:

  if (error)
    close
    return

  if (error) 
    deallocate; 
    close; 
    return
where by using goto you can put those handlers as in a footnote of a function like

  if (error)
    goto error1

  if (error)
    goto error2

  error2:
    deallocate
  error1
    close
as it looks a bit neater

some languages like Zig for example have keyword defer, this to my understanding implements an alternative to this approach


👤 ashwinipatankar
Short Answer:

GOTO is used in very confined and careful manner. So, the statement that says "GOTO shall not be used" is only for the junior developers or newbies. Once someone gain experience, and knows what is going on, GOTO is safe to use.


👤 ncmncm
Linux uses goto statements to transfer control to another place in a function.

In a better language there would be little or no use for them, but Linux is still uniformly C.