0

Having looked at a few different C systems codebases (notably the kernels of BSD and Linux), I notice a liberal use of goto, even when it would be trivial to use a higher-level flow control construct like a loop or function call instead. Here's one example, from mm/mmap.c in Linux:

munmap_back:
    if (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
            if (do_munmap(mm, addr, len))
                    return -ENOMEM;
            goto munmap_back;
    }

munmap_back is not referenced anywhere else, so this code is exactly equivalent to

    while (find_vma_links(mm, addr, addr + len, &prev, &rb_link, &rb_parent)) {
            if (do_munmap(mm, addr, len))
                    return -ENOMEM;
    }

Since Linux and BSD were developed by very competent people, I assume there are some advantages or reasons for this style. What are they?

Brennan Vincent
  • 10,736
  • 9
  • 32
  • 54
  • 2
    goto isn't always bad.It's just good in some situations. – Christo S. Christov Jan 10 '15 at 22:42
  • @CodingChief : I know, and my question isn't about cases where `goto` is legitimately the only good way to express control flow (error handling in a language like C that lacks exceptions comes to mind). In many examples, including the one I gave, the `goto` is trivially equivalent to a loop. – Brennan Vincent Jan 10 '15 at 22:44
  • 4
    I don't think we can answer why someone happened to write in a particular style. – Barmar Jan 10 '15 at 22:44
  • BTW, you should remove the `goto` from the equivalent code. – Barmar Jan 10 '15 at 22:45
  • 1
    Chapter 7 @ https://www.kernel.org/doc/Documentation/CodingStyle is encouraging and explaining some benefits of goto. – Jens Wirth Jan 10 '15 at 22:46
  • @Barmar totally agreed. Altough this style isn't used nowdays it remains just a different way to say the same thing : to loop. – Christo S. Christov Jan 10 '15 at 22:47
  • @haccks: The example I gave can't be older than the early 1990s, when Linux began. – Brennan Vincent Jan 10 '15 at 22:48
  • 1
    There could be an argument for code size and efficiency - leveraging near jumps for re-used local code segments, perhaps? This could also save compile time by reducing the amount of optimization work the compiler needed to do... consider a few decades ago when a few MB was a lot of ram and 33MHz was a smoking fast CPU... – J... Jan 10 '15 at 22:49
  • @JensWirth Does the posted code fit any of the reasons that document says to use `goto`? – Barmar Jan 10 '15 at 22:49
  • @Barmar One expects we would need more context to understand the reasons for OP's code snippet - if more than one area of the method was using `munmap_back`, for example, it would shed some light on why the author chose to write it that way (etc). – J... Jan 10 '15 at 22:51
  • Programming styles evolve with the years. In the early 90s, there may not have been that many super competent C coders. But "`goto` is bad" is more a comment on newbie code that abuses it *everywhere*. – Jongware Jan 10 '15 at 22:51
  • 1
    @J... He says in the question that `munmap_back` is not referenced anywhere else. – Barmar Jan 10 '15 at 22:53
  • 1
    Also keep in mind that C does not have any native exception handling... `goto` was (and is) a pretty common tool for implementing exception handling behaviour. – J... Jan 10 '15 at 22:53
  • 2
    One possibility is that this code was originally written in assembler, and then someone did a mechanical translation to C. – Barmar Jan 10 '15 at 22:53
  • @Barmar Missed that... fair point. Still, if the possibility existed at the time of writing that it might be needed elsewhere it may have been written in that style just in case. Hard to say. – J... Jan 10 '15 at 22:53
  • 1
    @BrennanVincent "... can't be older than the early 1990s" - which would still be over two *decades* ago. Modern C compilers are *very* proficient in generating goto's (jumps) *for you* via optimization techniques. There is little-if-any reason in modern day application code for `goto`. Code that is *specifically* optimized (or lack thereof) for specific architecture code generation (such as kernel code) plays by a somewhat different set of rules then us mere mortals. Your posted code is easily (and efficiently) doable with `while` as you've demonstrated. – WhozCraig Jan 10 '15 at 22:54
  • 1
    @Barmar the question is general and the code is an example – Jens Wirth Jan 10 '15 at 22:54
  • 1
    @JensWirth The question implies that this is a typical use. Or that he wants to know why `goto` is used in code like this, that doesn't really need to use it. – Barmar Jan 10 '15 at 22:56
  • It is normal. Teachers tell to students that `goto` is ultimate evil but they (teachers) are not programmers - at least most of them have not programmed commercially never. But it is normal to use goto in many cases - normal operator. – i486 Jan 10 '15 at 22:56
  • In the absence of extra information, there is no obvious reason why that `while` loop was written out with a `goto`. However, there are other circumstances under which `goto` can be reasonable. See [Is it ever advantageous to use `goto` in a language that supports loops?](http://stackoverflow.com/questions/24451) and [GOTO still considered harmful?](http://stackoverflow.com/questions/46586); also [Bose-Hibbard sort](http://stackoverflow.com/questions/4484024) for an example of what unconstrained use of `goto` meant in the early '60s. – Jonathan Leffler Jan 10 '15 at 22:57
  • there's a possibility that that code was translated from assembler. – Jasen Jan 10 '15 at 23:11

3 Answers3

1

There is no need or reason to use a GOTO to accomplish a loop. Sometimes in a deep nested loop GOTO can be used to get out of the loop if a catastrophic condition is detected. Personally I do not do this either.

BGStack
  • 1,134
  • 1
  • 7
  • 6
0

It is far from the only answer, and one which was already mentioned in the comments, but a very common and justified reason for using goto in C is for exception-handling. See, for example, the MPICH communication library that implements the MPI standard. Nearly every function uses goto as a means for handling errors (e.g. http://git.mpich.org/mpich.git/blob/HEAD:/src/mpi/rma/win_allocate.c). Using goto makes for code that is readable, efficient, easy-to-maintain and hard-to-break (relatively, of course, as MPICH development is not for novices).

In the case of MPICH, goto is used to ensure that, when handling an error, resources are cleaned up (especially that locks held by the current function are released) and that a useful error message is printed (assuming this is configured to be active) while still exiting through the non-error path, because that enables the errors to be propagated up the stack and ultimately handled by the user, as opposed to just aborting.

Jeff Hammond
  • 5,374
  • 3
  • 28
  • 45
0

GOTO is used to achieve the 'only one exit place' paradigm in functions. Without it, your code would be bloated with 'if previous succedded' and deeply indented.

Please read chapter 7 here:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/CodingStyle

René Kolařík
  • 1,244
  • 1
  • 10
  • 18
  • 1
    No it wouldn't if you organised your functions properly. Using `goto` is a sign of poorly thought out logic. Although allowed, it belongs to BASIC. WRT @JonathanLeffler. – Weather Vane Jan 10 '15 at 23:52
  • 3
    Feel free to prove your statement - you can start with refactoring Linux kernel :) – René Kolařík Jan 10 '15 at 23:59
  • 1
    My only proof is that I never use `goto` in C and I never get deeply indented, because once that starts to happen it's time to rethink the logic. – Weather Vane Jan 11 '15 at 00:02
  • @WeatherVane And have you recently written anything as powerful as an operating system kernel...in particular one that can fit in <2MB RAM and still be useful on a 386? – J... Jan 12 '15 at 09:51
  • @J... you are right, the question was about OS kernels, and I haven't written one such as asked, only simple ones for embedded controllers (in assembler) - although I did make a start at an OS for a PC before realising how much I had taken on. There is one good reason for using `goto`, which is to provide a common exit point where some clean-up can be done, and in fact I've just looked through some of my C projects and found that I *have* used `goto`, so I will cop to it rather than delete my earlier comments. – Weather Vane Jan 12 '15 at 18:13
  • 1
    @WeatherVane Just to be clear, I wasn't implying anything other than to point out what seemed to be something of an anecdotal fallacy http://en.wikipedia.org/wiki/Misleading_vividness ...also perhaps http://en.wikipedia.org/wiki/Mind_projection_fallacy or http://en.wikipedia.org/wiki/Psychologist%27s_fallacy – J... Jan 12 '15 at 20:23
  • @J... and others, point taken thank you. – Weather Vane Jan 12 '15 at 20:31