Slashdot Mirror


Empirical Study On How C Devs Use Goto In Practice Says "Not Harmful"

Edsger Dijkstra famously opined in 1968 on the danger of Goto statements. New submitter Mei Nagappan writes with a mellower view, nearly 50 years later: By qualitatively and quantitatively analyzing a statistically valid random sample from almost 2 million C files and 11K+ projects, we find that developers limit themselves to using goto appropriately in most cases, and not in an unrestricted manner like Dijkstra feared, thus suggesting that goto does not appear to be harmful in practice. (Here's the preprint linked from above abstract.)

21 of 677 comments (clear)

  1. why? by Anonymous Coward · · Score: 5, Insightful

    Is that because they were warned by Djikstra that it would be harmful to use it haphazardly? Or is it for some other reason?

    1. Re:why? by ShanghaiBill · · Score: 3, Insightful

      Is that because they were warned by Djikstra that it would be harmful to use it haphazardly? Or is it for some other reason?

      1. Because if you use goto in a class assignment, you lose points.
      2. Goto is easy to avoid, and is a symptom of a poorly designed program.
      3. Some compilers don't even try to optimize a function containing a goto.

      I have occasionally used goto as a quick hack, usually to handle error conditions.
      When I later go back and refactor the code, it is always cleaner and more readable without the goto.

    2. Re:why? by sjames · · Score: 4, Insightful

      1 and 3 are certainly true. 2 is not always. For example, if an error condition requires unwinding such as releasing resources. Compared to deeply nested ifs and having to essentially duplicate the entire control flow in the bottom half of the function, gotos can make things much more readable and even improve performance.

      Perhaps a better statement is that goto will be found in code that is either very well designed or very poorly.

    3. Re:why? by fahrbot-bot · · Score: 4, Insightful

      There may be a better pattern, but in a few cases ...

      Like many (most?) tools, the GOTO can be used and abused. Only pendants are convinced the issue is black and white.

      --
      It must have been something you assimilated. . . .
    4. Re:why? by Anonymous Coward · · Score: 5, Insightful

      If I worked for someone as rigidly blind as yourself, I'd have left years before you "fired me", "manager in your dreams".

      THE ONLY RULE is that rules are meant to make you think carefully before you break them.

      Rules are for the guidance of the wise and obedience by fools.

      You, sir, are a fool.

    5. Re:why? by tepples · · Score: 5, Insightful

      How many levels of nested if blocks are you willing to tolerate solely in the name of avoiding a single use of the keyword goto?

    6. Re:why? by Chris+Mattern · · Score: 3, Insightful

      If operator overloading is only useful for mathematical constructions, why not simply bake those things into the language and be done with it

      Because there are an infinite number of possible mathematical constructions. You can't bake them all into the language; you need to provide facilities for the programmer to write his own.

    7. Re: why? by Anonymous Coward · · Score: 2, Insightful

      I dunno, I think I would rather listen to Linus, a guy that maintains a whole OPERATING SYSTEM, than some scrub hipster developers that think an incredibly useful and provably more efficient command is A Bad Thing.

      Also, protip, all that branching shit it compiled the same way your hated gotos are.

    8. Re:why? by ClickOnThis · · Score: 3, Insightful

      I was wondering that too, but, there is another one.... what if the real issue was simply Djikstra's underestimation of how obvious the pitfalls with goto are.

      1968 was the year Djikstra wrote his article. At that time, arguably the dominant languages (FORTRAN IV and maybe BASIC) did not have structured control-flow constructs such as if-then-else, do-while and begin-end blocks. Others that contained these constructs (PL-I and Algol come to mind) were struggling for mind-share.

      Without structured control-flow constructs, one is pretty much forced to write goto statements everywhere. I think Djikstra's cautioning against the use of gotos was also a call to abandon them in favor of the structured approaches that the new languages supported. And he was right: if you're using gotos to replace structured control-flow, then you're abusing gotos.

      --
      If it weren't for deadlines, nothing would be late.
    9. Re:why? by zieroh · · Score: 4, Insightful

      An improperly structured program, will behave however the compiler felt like making it behave when it turned your lines of gibberish posing as code into machine instructions that actually manipulate registers and memory spaces.

      This misses an important point that (apparently) needs stating: complex and/or deep nesting makes code more difficult to understand by programmers (perhaps even the one that wrote the code in the first place). A simple goto-based assertion macro goes a long way toward linearizing the flow of code such that it is simple to understand. If the compiler has trouble with that, then the guy that wrote the compiler needs to try harder.

      --
      People who say "sheeple" have about as much sophistication as an AOL user, and in fact are probably actually AOL users.
    10. Re:why? by beelsebob · · Score: 4, Insightful

      The problem is that the above is a remarkably simple case. The reality for a lot of cases where goto gets used for error handling is that with the above what you would end up writing is:

      bool success = doSomethingThatMightFail();
      if (success) {
              success = doSomethingElseThatMightFail();
              if (success) {
                      success = doMoreFailingStuff();
                      if (success) {
                              success = yepMoreFailingStuff();
                              if (success) { ...
                              }
                      }
              }
      }
      if (!success) {
                cleanupWork
      }

      Meanwhile with a reasonably constructed macro to wrap his pattern, you end up with:
      bool success = true;
      CHK(doSomethingThatMightFail());
      CHK(doSomethingElseThatMightfail());
      CHK(doMoreFailingStuff());
      CHK(yepMoreFailingStuff());

      end:
      if (!success) {
              cleanupWork
      }

      That's much easier to read, and just as safe.

      Don't get me wrong, in a language where you can use exceptions for this, or better yet, the error monad, you should absolutely use those more abstracted concepts, but in plain C, this really is the best approach to handling errors in code where everything you do could go wrong.

    11. Re:why? by dargaud · · Score: 4, Insightful

      yeah, GOTO the end and do some cleanup and/or error reporting, which is common to all the gotos. I don't see a problem with that. It's clear, simple and avoid heinous if/else deep nestings.

      --
      Non-Linux Penguins ?
    12. Re:why? by ShanghaiBill · · Score: 1, Insightful

      I'd love to see you write the error handling for a C function that needs to acquire multiple resources where any such acquisition can fail.

      This is the way I would do it:

      void
      foobar()
      {
          int resourcesUsed = R1 | R2 | R3;
          if (acquireResources(resourcesUsed)) {
              doWork();
              releaseResources(resourcesUsed);
        }
      }

      Low level details like acquiring and release resources, and error handling, do not belong in the main flow of your logic. They should be moved to separate library routines, where they are written and debugged once, and then used wherever necessary.

      The problem with "goto error handling" is that it is a situation that should never arise in a well designed program.

    13. Re: why? by Darinbob · · Score: 5, Insightful

      What if I actually am an expert? Am I still bound by your superstitions about goto?
      It's one thing to tell a student or beginner to avoid goto, but another thing to place an absolute prohibition on them.

      The original goto-considered-harmful paper was written at a time when structured programming was extremely rare, spaghetti code was common, and the flowchart was a common design method. We're decades past that time though and the general programming style everywhere is to be highly structured. So the same repulsion about using goto is no longer necessary, we know enough to not use it at a whim but should be allowed to use it when it is indeed appropriate in languages which do not have the necessary structured constructs to avoid it.

  2. How much unsafe use has Dijkstra prevented? by suutar · · Score: 3, Insightful

    Goto is being used safely (relatively) now, but would have the programming practices that cause that to be true become so prevalent without his warning that it had potential for problems?

  3. What's the term for a prophylactic prediction? by myvirtualid · · Score: 5, Insightful

    There is an implication that Dijkstra was wrong about the goto - the implication being based on how conservatively it is used.

    Perhaps it is wiser to conclude that the goto is used so conservatively because Dijkstra was right and that programmers have, in general, taken his wisdom to heart and avoided the goto except for those instances where, properly documented, it is the best tool for the job.

    (By prophylactic prediction I mean the sort of warning or planning that completely forestalls the danger predicted, through awareness, preparation, etc. Kind of like the Y2K non-event.)

    --
    I'm here EdgeKeep Inc.
  4. all languages can be abused by Anonymous Coward · · Score: 2, Insightful

    All languages can be abused.

    goto is no different than if nests or giant nested for loops or any other maddening crap people can come up with. If you look at the code most C compilers come up with they are not afraid of a goto...

    Goto used correctly is a good tool. Its just a tool. Do not treat it as something bad or good. Look to how it is used.

  5. Way to bury the lead by Chess_the_cat · · Score: 5, Insightful

    Headline should read "Thanks to Dijkstra's warning, GOTO in practice not harmful."

    --
    Support the First Amendment. Read at -1
  6. Re:GOTO is a crutch for bad programmers by sjames · · Score: 3, Insightful

    So abuse loops and nesting when you have no intention of looping? And use break which is just goto lite?

    That always seems like standing on one's head to please the compiler.

  7. Re:GOTO is a crutch for bad programmers by ShanghaiBill · · Score: 2, Insightful

    This is simpler, cleaner, and avoids the goto:

    void func() {
        if (AquireResource1()) {
            if (AquireResource2()) {
                if (AquireResource3()) {
            DoStuffWithResources();
            CleanUp3();
                }
                CleanUp2();
            }
            CleanUp1();
        }
        return;
    }

  8. I agree by NickFortune · · Score: 4, Insightful

    People forget that Djiksrtra wrote his famous missive back when the dominant languages were PL/1 and Fortran and goto was the main mechanism for flow control.

    Dijkstra's point was perfectly sensible and a valid at the time. I'm just not sure that it deserves to be elevated to the status of Eleventh Commandment.

    --
    Don't let THEM immanentize the Eschaton!