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.)

677 comments

  1. I prefer the Comefrom statement by Anonymous Coward · · Score: 5, Funny

    It gives me so much more flexibility and power. The computed comfrom is even better.

    1. Re:I prefer the Comefrom statement by istartedi · · Score: 1
      --
      For all intensive purposes, "whom" is no longer a word. That begs the question, "who cares"?
    2. Re:I prefer the Comefrom statement by Anonymous Coward · · Score: 0

      The computed comfrom is even better.

      Calculated kink.

    3. Re:I prefer the Comefrom statement by lsatenstein · · Score: 1

      I just love COBOL's Alter clause. I use it everywhere to confuse the support people

      --
      Leslie Satenstein Montreal Quebec Canada
  2. 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 Anonymous Coward · · Score: 0

      Because if they used it in stupid ways it would quickly make their life much harder.

    2. 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.

    3. Re:why? by firewrought · · Score: 5, Interesting

      Is that because they were warned by Djikstra that it would be harmful to use it haphazardly?

      Programmers are more used to structuring their code (using functions, modules, etc.) and using best practices (minimizing globals, separation of concerns, etc.). This was not so much the case in the late 60's. That, combined with the "goto stigma", means that average developers avoid goto usage and good developers know when it's worth it.

      We saw a similar backlash with the concept of operator overloading. People abused it in C++, the Java designers overreacted and prohibited it, but most languages since then recognize that "yeah, operator overloading's really nice when you're building an API for mathematical constructs" (like complex numbers, quaternions, and matrices). So it's there in C#, Python, D, Rust, Scala, but (from the little I've seen) people seldom abuse it these days.

      --
      -1, Too Many Layers Of Abstraction
    4. Re:why? by Anonymous Coward · · Score: 5, Interesting

      Really? You loose point for what is really the most sane way to handle cleanup in C? Have the instructors in those courses actually done any real work outside of academia? This is a very common pattern that I've seen in almost every large C code base that I've worked on.

      static int
      do_some_work (context_t context,
                    int x,
                    error_t **error)
      {
          int rv = 0;
          database_t *db;
          data_t v;

          db = get_db (context, error);

          do some work ...

          v = compute_v (context, db, error);
          if (!v)
              goto out;

          more work ...

      out:
          return rv;
      }

      It makes it so much cleaner and easier to read.

    5. Re:why? by sjames · · Score: 2

      I think that's likely. It became such a taboo that developers tend to think it over thoroughly before actually using it.

    6. Re:why? by goose-incarnated · · Score: 1

      "yeah, operator overloading's really nice when you're building an API for mathematical constructs" (like complex numbers, quaternions, and matrices). So it's there in C#, Python, D, Rust, Scala, but (from the little I've seen) people seldom abuse it these days.

      Why is it there, then? If operator overloading is only useful for mathematical constructions, why not simply bake those things into the language and be done with it rather than provide operator overloading which can, amongst other things, also be used to build those libraries?

      After all, those are libraries. They can easily be provided as part of the language with no impact to the actual language or the language usage... if that is all that overloaded operators are used for! Unfortunately the truth is that overloaded operators are a bad idea but language designers have a checklist of items that their new language needs to have to get in with the damn hipsters. Operator overloading is one of those things.

      --
      I'm a minority race. Save your vitriol for white people.
    7. Re:why? by Bengie · · Score: 4, Informative

      There may be a better pattern, but in a few cases, I found Goto a lot easier to read than 20 layers of nested If statements. Essentially a situation where you have a pipeline of code doing one stage at a time, but you need it to immediately stop if any one of those stages did not work.

      Not to mention all conditional statements and loops are just a subset of goto. Try writing some ASM.

    8. Re:why? by Austerity+Empowers · · Score: 4, Interesting

      Computer Science and Computer Programming are two different things. The academics are always on a quest for purity, people who work for a living want to get things done as cleanly and quickly as possible. Frequently the two minds align, but you won't convince the academic your goto is pure anymore than he can convince you to rewrite the code to remove it (which you could do).

    9. 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.

    10. Re:why? by Anonymous Coward · · Score: 0

      He/she never said it was the correct way, just that it was a good way. They way you talk about it make it sound like you have just been brainwashed by cs people.

    11. Re:why? by Anonymous Coward · · Score: 0

      I seriously doubt he wants to work for McDonald's.

    12. Re:why? by TheCarp · · Score: 1

      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.

      Its easy to accidentally cut yourself with a knife, its also easy to see the danger and most people learn to use one without cutting themselves pretty quickly. The pitfalls are easy to see, and making mistakes causes pain.... much like Goto.

      The problems with it are easy to see if you just use it a few times. I learned to use goto in applesoft basic, after my first session of learning C, it was obvious I would never want to use goto again.

      In fact, after learning a bit of C, it was far less obvious that I would want goto at all than that I would generally not.

      --
      "I opened my eyes, and everything went dark again"
    13. 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. . . .
    14. 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.

    15. Re:why? by kenaaker · · Score: 2
      And, the get_db acquired locks and did mallocs, compute_v created a new thread to handle something asynchronously.

      So, bailing out leaves dangling threads, leaking memory, and deadlocks that show up the next time the function is entered.

      It's the easy way out only once.

    16. Re:why? by Anonymous Coward · · Score: 0

      Really!? As opposed to

      if (!v) {
            { more work }
      }
      return(rv);

      Your example is not easier to read. The flow of code is disrupted by a completely unnecessary goto that says you didn't actually plan out do_some_work before you started writing it.

      The real goal of structured programming is make the author think about what they're trying to do, before the author tries to make the computer understand what they want it to do.

    17. Re:why? by bunratty · · Score: 1

      The goto statement isn't the issue. The issue is non-structured programming, which includes the use of goto, break, continue, multiple returns from a procedure, exceptions, longjmp, and anything else that interrupts the normal control flow of a program. The idea is that to understand a program, you need to understand all the ways the flow of control can occur. Each time you conditionally break the flow of control, you're potentially doubling the number of ways control could flow through the program, making it potentially exponentially harder to understand and test.

      Once a co-worker proudly showed me how he wrote the following construct:
      do {
      //some code
      if (condition) break;
      //more code
      if (another condition) break;
      //yet more code
      } while (0);
      to avoid goto statements. My reaction is that goto statements would more clearly express the jumps in the control flow. A do-while indicates a loop, but it isn't a loop; it's gotos in disguise.

      Some programmers take this idea to an extreme and even write code such as:
      int abs(int x) {
      int retval;
      if (x >= 0) retval = x;
      else retval = -x;
      return retval;
      }
      In this case, multiple return statements would make the code simpler, not harder to understand. Similarly, using exceptions wisely can make code easier to understand, not harder.

      The bottom line is that as a general rule it's best not to break the flow of control. But a good programmer will know when it makes sense to do so, and if a goto statement makes sense, it can be the clearest way to express such a break.

      --
      What a fool believes, he sees, no wise man has the power to reason away.
    18. Re:why? by Anonymous Coward · · Score: 0

      There may be a better pattern, but in a few cases, I found Goto a lot easier to read than 20 layers of nested If statements. Essentially a situation where you have a pipeline of code doing one stage at a time, but you need it to immediately stop if any one of those stages did not work.

      Not to mention all conditional statements and loops are just a subset of goto. Try writing some ASM.

      20 layers of nested ifs is already a disaster.

    19. Re:why? by Anonymous Coward · · Score: 0

      MAtrices aren't part of the standard library, you bloody moron.

      Ergo, they have to be written in with a library.

      Which library has to be written in the standard language.

      Which means the fucking standard language has to have operator loading, you blithering fuckwit!!!!!

      Also, do you have ANY CLUE what the normal English phrase "such as" means? ANY CLUE WHATSOEVER????

      FFS, codemonkeys shining a torch out their arse because they've obeyed "No GOTO, No Operatoroverload!" and think that that means they're smarter than everyone who doesn't subscribe to that witchcraft.

    20. Re:why? by TheCarp · · Score: 1

      I guess one needs to actually work for you to find out why its crap.

      I don't work with C much but generally speaking, that looks really clear and easy to follow to me. The case
      itself may be simple enough to use a return statement directly in place of the goto but, if you needed to do any further massaging of the output that was common to all/most return paths, that goto seems like a fine way to do it to me....or do you want to put that in yet another function and let the compiler handle optimizing/inlining if need be?

      --
      "I opened my eyes, and everything went dark again"
    21. Re:why? by Anonymous Coward · · Score: 0

      There was supposed to be some cleanup code for the database_t object at the end of the function, but forgot to add it while playing with the code tag. :-)

    22. Re:why? by Anonymous Coward · · Score: 0

      It may be because when he wrote that, languages with more civilized control structures were not in wide use.
      He was writing to convince folks that these were useful and necessary.
      He was successful/correct, which is why folks do not need to misuse goto's today.

      The story is more a report on the nice legacy Djikstra than the evils of goto.

    23. Re:why? by Anonymous Coward · · Score: 0

      setjmp-based exception handling. With some preprocessor hacking, you can emulate try-catch blocks which function very similar to C++.

    24. Re:why? by bobbied · · Score: 1

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

      I think it's the result of "lint" output that would harp about "goto" statements and gung-ho CS students that took the "don't use GOTO" message to heart...

      --
      "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
    25. Re:why? by bobbied · · Score: 1

      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.

      Oh they have one more purpose... To become the coding standard for a new language and be enforced by the compiler pre-processor so the fools who don't want to follow the rules won't have a choice.... Don't believe me? What was all this JAVA hoopla?

      --
      "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
    26. Re:why? by tepples · · Score: 1

      or do you want to put that in yet another function and let the compiler handle optimizing/inlining if need be?

      Yes. Performance is something you add after correctness and understandability.

    27. 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?

    28. Re:why? by Anonymous Coward · · Score: 2, Interesting

      It's crap because he's regurgitating what he learned in programming class, from a professor who repeated the mantra "goto bad". Consider the quote from Knuth.

      "Please don't fall into the trap of believing that I am terribly dogmatical about [the goto statement]. I have the uncomfortable feeling that others are making a religion out of it, as if the conceptual problems of programming could be solved by a single trick, by a simple form of coding discipline!." -Knuth

      That being said, I demand a flow chart included in the documentation when goto is used for anything other then error handling. Those who demand to use the goto are willing to write the flowchart.

    29. Re:why? by tepples · · Score: 1

      MAtrices aren't part of the standard library, you bloody moron.

      Perhaps goose-incarnated is trying to claim that every mathematical type on which it makes sense to define infix operators ought to be included in the standard library. Then the linker would just leave out the operations for all types that a particular program happens not to use.

    30. 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.

    31. 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.

    32. Re:why? by Anonymous Coward · · Score: 1

      And if I was your CTO I would fire you for that comment: academic code is a very beautiful thing that rarely performs to industry standards.

    33. Re:why? by goose-incarnated · · Score: 0

      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.

      There are also an infinite number of arithmetic constructions, but it's still possible to support them all within a range. All languages already do this. I'm saying that they should extend this to those things that operator overloading is most used for. Then there wouldn't be any reason to overload the operators in the first place.

      --
      I'm a minority race. Save your vitriol for white people.
    34. Re:why? by Anonymous Coward · · Score: 0, Troll

      4

      Filter error: You can type more than that for your comment.

    35. Re:why? by Anonymous Coward · · Score: 1

      I've found a need to use a GOTO statement (in C, C++, or C#) maybe a 2-3 times per year, usually when dealing with nested loops, or with a switch statement inside a loop. Sometimes refactoring makes more sense but isn't practical for time-constraint reasons, in other cases using a GOTO is the most-elegant or most-perfomant option.

    36. Re:why? by tepples · · Score: 1

      Ought every language's standard library to include set addition and Cartesian product, vector addition and multiplication, matrix addition and multiplication, polynomial addition and multiplication, Minkowski addition, Galois field element multiplication, nimber addition and multiplication, and every other meaning of addition and multiplication known to mathematicians?

    37. 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.
    38. Re:why? by SuricouRaven · · Score: 1

      int abs(int x) {
      if (x >= 0) return x;
      else return -x;
      }

      Still no gotos! And it's about as simple and readable as it can get.

    39. Re:why? by itzly · · Score: 1

      No, but neither should the programmer overload the '+' and '*' operator to do all of those things.

    40. Re:why? by Anonymous Coward · · Score: 0

      Yep, because the code I saw in those days using GOTO's was because people didn't know how to do things a better way (or prematurely optimizing). Basically, by warning us of the dangers, and CS forcing students not to use them (most students would use them wrong) we have taught several generations better ways to program. Of course, you can find a good use for every language construct, GOTO being an example, you can also misuse every single language construct with GOTO the easiest and worst to misuse. CS should teach in higher level classes proper uses of GOTO's, etc.

    41. Re:why? by Anonymous Coward · · Score: 0

      When goto made slashdot before a poster claimed to have seen it used properly. It is the problems that are caused when goto is used improperly that are more than harmful.

    42. Re:why? by gnasher719 · · Score: 1

      However, if you write C++ code, then this do { ... } while (0) thing makes really sense. C++ doesn't like goto's. You can't goto over the constructor of an object. So

      if (condition) goto abc;
      int i = 0;
      abc: ...

      isn't accepted by the compiler. But a break inside a "loop" is no problem.

      The second one may be to make code more debuggable. If there's a single return statement, I can set a breakpoint and check what the function returns. Of course anything that can be done can be overdone.

    43. Re:why? by ClickOnThis · · Score: 1

      How about:

      int abs(int x)
      {
          return (x >= 0) ? x : -x;
      }

      --
      If it weren't for deadlines, nothing would be late.
    44. Re:why? by david_thornley · · Score: 2

      Every "goto out;" can be replaced by a "return rv;" which says explicitly what it does. The dislike of multiple return statements in a function is based on academic thinking, not reality.

      Now, if you were doing more processing after "out:" than just a return statement, there'd be a case for what you're doing. Piling up end-of-function code like that is ugly, but there's often no way to do it better in C. In C++, you'd use RAII for resource management and not need any exit code.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    45. Re:why? by ilsaloving · · Score: 0

      Why is this modded to -1?

      What the AC said is absolutely correct, although admittedly they could have been a tad more tactful about it.

    46. Re:why? by david_thornley · · Score: 2

      Not all academics are against goto. Knuth is an academic, and he wrote on the structured uses of goto shortly after Dijkstra's edict. (Some of these uses have since been absorbed into constructs like "break" and "continue", but "break" can't break out of more than one loop at a time and "goto" can.)

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    47. Re:why? by Anonymous Coward · · Score: 0

      Only pendants are convinced the issue is black and white.

      How poignantly self-describing.
       

    48. Re: why? by ilsaloving · · Score: 0

      Just because an expert does it, doesn't mean everyone should. An expert developer has a much better structural understanding of how a system works, and is better able to judge whether going against conventional wisdom is beneficial or not, risky or not, etc.

      Anyone else doing is is just doing the programming equivalent of the cargo cult.

    49. Re:why? by Megane · · Score: 1

      20 layers of nested ifs is already a disaster.

      The real fun comes when every one of those layers has an else block. So you end up with about 300 lines of code, then come up on a dozen else error("some message"); else error("another message"); else error("another twisty message all different"); else etc. To paraphrase the real estate agent's motto: locality, locality, locality!

      And of course the legacy code that I had to work on did all of this in main(). He also had a fondness for putting assignments inside the if statements, like: if (retval = longnamefunction(parameter, anotherfunction(parm, pram), paremater, &pretamer) and they would go to about column 120 or so

      --
      #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
    50. Re:why? by Anonymous Coward · · Score: 0

      How is this modded -1? It's a perfectly clear answer to a perfectly clear question!

    51. Re:why? by Anonymous Coward · · Score: 0

      Benefits to do/while(0) blocks:

      1. you get an extra scope of disposable local variables,
      2. it is analogous to an inline function with multiple returns, but without the extra overhead of calling and returning, and
      3. it works well in macros as atomic sections of code to help simply repetitive algorithms, especially when manually unrolling loops for better optimization (regardless of how well/poorly a compiler will perform).

      While goto statements would do an equivalent job in the snippet you provided, it may not be the best answer for how that snippet could be used/abused.

      Your mileage may vary.

      I would have done the abs as int abs(int x) { return x 0 ? -x : x; }

    52. Re:why? by david_thornley · · Score: 1

      First, how many things do you want to bake into the language? Should every programming language have built-in matrices, tensors, quaternions, and complex numbers, and whatever I'm missing (and I know it's some things)?

      Second, complex numbers are in the C++ standard library. They are implemented using operator overloading, because that's the most straightforward way to do it.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    53. Re:why? by goose-incarnated · · Score: 1

      Ought every language's standard library to include set addition and Cartesian product, vector addition and multiplication, matrix addition and multiplication, polynomial addition and multiplication, Minkowski addition, Galois field element multiplication, nimber addition and multiplication, and every other meaning of addition and multiplication known to mathematicians?

      No, but there's no reason to not include the more common datatypes and operations on those datatypes instead of providing the facility for the programmer to implement them. A few datatypes with operations covers maybe 95% or more of mathematical constructions.

      Analogously, there are many many string operations - yet most languages have a builtin string datatype. Turns out this was a good idea. Do the languages cover all operations on strings? No, they don't, but they provide enough operations that overloading is not even needed for most operations.

      Wouldn't it be stupid if language designers said "Well, we don't provide string copy operations nor string datatypes, but you can use the operator overload to write your own string datatype!" This is what they are doing with operator overloading: mostly they get used for matrices or similar. Anyone doing work in those fields you listed above would be better served by matlab.

      --
      I'm a minority race. Save your vitriol for white people.
    54. Re:why? by zieroh · · Score: 0

      If you worked for me, and you wrote garbage like that, I would give you a verbal warning and show you how to do it correctly. If you did it again, I would give you a documented written warning. The third time, I would fire you.

      This kind of rhetoric doesn't exactly lead to meaningful discussion, and it indicates I will probably be unable to sway you with reason or logic. Thus, I'll simply state that you're a pedantic idiot who appears to be more interested in stupid ideals than practical solutions.

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

      He/she never said it was the correct way, just that it was a good way.

      It is NOT a "good way". In many applications, including anything involving safety, that code would be considered negligent. It is a blatant violation of MISRA standards. Organizations tasked with writing reliable code often have their compilers configured to refuse to even compile code like that.

      A competent programmer should be able to rewrite it to be simpler, easier to understand, and compliant with industry standards.

    56. Re:why? by Anonymous Coward · · Score: 0

      You could easily rewrite,

      if (!v)

                      goto out;

              more work ...

      out:

              return rv;

      as

      if (v)

              more work ...

      return rv;

      That seems like far more work than is necessary. Just say

      if (!v) return rv;

      So what if you have to write return rv; more than once? It's still less confusing than the goto indirection, and it avoids enclosing the entire content of the function in an if statement. Also, I generally find myself writing something that looks more like

      if (!v) return NULL;

      which avoids the problem of remembering that it should return a variable named rv or having to change from rv to return_value if you change the variable name.

      It's not impossible to write C code where goto is cleaner or more performant than the other options, but this isn't it. It's also pretty rare.

    57. 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.
    58. Re:why? by Anonymous Coward · · Score: 0

      I agree, but the basic problem is that it is not obvious which "{" and "}" belongs together. In basic if I have a "for i", I always close the loop with "next i", (with "next" a variable name is not required.

    59. Re:why? by Anonymous Coward · · Score: 0

      I have occasionally used goto as a quick hack, usually to handle error conditions.

      Yup. And exceptions where added to later languages to avoid this exact use of gotos.

    60. Re:why? by Megane · · Score: 1

      I think part of it was just the era, when FORTRAN still was a significant programming language. Its arithmetic IF was basically a triple GOTO statement, and you could literally go anywhere from it. Only being able to use numbers for labels, with no enforcement of numeric order, made it even worse.

      As long as you make the effort to use the standard (and more readable) control structures where they apply, the really weird stuff like error abort stuff then can stand out by its use of goto. I still don't feel that it's significantly more readable to abuse stuff like do { } while(0) (other than in a #define macro to ensure statement atomicity) over a "goto abort".

      --
      #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
    61. Re:why? by Anonymous Coward · · Score: 0

      My experience looking at old code is that many of the programmers had no idea of the pitfalls. They learned on the job, and if the program worked it was good, and if it didn't it was bad. People hadn't maintained much code, people learned on their own, and didn't have enough exposure to great programmers.

    62. Re: why? by TechyImmigrant · · Score: 1

      It's not complicated. Even novice programmers can understand goto error handling. Being an expert developer doesn't actually make a difference here. It just means you've done it more.

      --
      I should use this sig to advertise my book ISBN-13 : 978-1501515132.
    63. Re:why? by pla · · Score: 3, Interesting

      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?

      If GOTO would actually alleviate that problem for you - You've already done something very, very wrong.

      I have written a lot of code in my life - Thousands of projects, millions of lines of code (for whatever that means), across a dozen languages and twice as many platforms. And outside Assembly (and DOS batch, if you want to count that as a "language"), I have not ever encountered a situation where I thought to myself "gee, I could really improve this with a GOTO, if only everyone wouldn't laugh at me for it".

      I have, however, removed some pretty heinous uses of GOTO from other people's code. The most common one I see, people can't quite bring themselves to "return" from an error handler in the middle of a function, so they instead GOTO the end of it. Really??? Talk about missing the forest for the trees!

      I don't think I would so much call GOTO "harmful", so much as "completely unnecessary in any modern language".

    64. Re:why? by beelsebob · · Score: 1

      I'm intrigued, what do you think the "correct way" to do error handling in code where you have a whole sequence of actions where each can fail is? You have no exceptions, and you have no error monad, or good way to implement it either. Do you propose that you simply copy/paste the error handling and cleanup code everywhere?

      What's the "right way" to do this in C that everyone else is missing?

    65. 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.

    66. Re:why? by perpenso · · Score: 1

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

      The GP's statement was that he would fire someone for repeatedly writing the "garbage" code offered as an example, no for simply using a goto.

      What careful thought do you see in the code offered? I see code that is more difficult to recognize as conditional because it is not indented. Such indentation is important because we often glance / skim through code while trying to get an idea of its flow.

    67. Re:why? by beelsebob · · Score: 2

      The reasoning behind not having multiple return statements is the exact same reasoning behind not using goto, so you're basically solving nothing here.

      Also, the example given is a poor one, it has only one place where an error can be generated (which is not the case you should address with goto, instead, the case where you have lots of steps, each of which could fail is), plus, it doesn't have any real cleanup work to do (e.g. it's entirely reasonable to expect that you may need to deallocate buffers you were working with etc when you fail).

    68. 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 ?
    69. Re: why? by Anonymous Coward · · Score: 0

      The moment C gains exceptions, I'll stop using GOTO.

      (actually, I did that, and now use setjmp / longjmp instead, which is really just goto taken to another level)

    70. Re:why? by punman · · Score: 2

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

      I think necklaces should be left out of this. You probably mean "pedant."

    71. Re:why? by jschultz410 · · Score: 1

      Funny! Using goto statements is the only sane way to handle errors and stack unwinding in C. If C had exceptions that might be a different story but ...

    72. Re:why? by jschultz410 · · Score: 1

      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. I'll bet it is gobbledy gook.

    73. Re:why? by perpenso · · Score: 1

      There was supposed to be some cleanup code for the database_t object at the end of the function, but forgot to add it while playing with the code tag. :-)

      Many of us assumed there was such cleanup code when we found the example lacking. Perhaps if there had been bailouts from multiple levels of nested code, but even then goto is not necessarily the best option.

    74. Re:why? by Anonymous Coward · · Score: 0

      Usually there's code between out: and return. But programmers used to writing code like this will sometimes write it that way even when there is no cleanup code. It doesn't bother me, you get used to it. Linux kernel code is often like this. Having some goto out's sprinkled through the code is the least of the problems with using return codes for error handling and reporting.

    75. Re:why? by Anonymous Coward · · Score: 0

      There is also the simpler:
      if (!v) {return rv}.

    76. Re:why? by Brett+Buck · · Score: 1

      You win! I was showing some newbies an example of that yesterday. With a lot of error checking, and indenting that Wirth would have approved of, the inner statements in the deepest loop wouldn't have fit on the screen.

            The alternative chosen was *multiple subroutine exits*, which is arguably much worse than a few GOTOs.

            Brett

    77. Re:why? by BlueMonk · · Score: 1

      All fine and good when there's no clean-up to be done. However, if you're in an error handler after opening a database connection, creating a temp file, and allocating a block of shared memory, now you've just leaked resources all over the place by skipping all the clean-up. Or you have to duplicate all that clean-up in this and every subsequent error handler within the function.

    78. Re:why? by perpenso · · Score: 1

      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?

      Actually each nested level would need its own goto.

      And I probably wouldn't start thinking about goto until 3 levels, and in many such situations I find a way to refactor things without goto. I am assuming large multiscreen blocks of code with 3. As the blocks get shorter and most/all the nesting appears on a single screen then the number goes up.

      Keep in mind that goto has a readability penalty in that the lack of indentation masks that a block of code is conditional. I guess I'm weird but I like to write code with the intent of handing it off to someone else so I can move on to something new, but I want to make things easier for the next person.

      Also keep in mind that for some compilers the issue is more than a goto statement appearing in source code. The compiler may not attempt certain optimizations in code when a goto is encountered.

    79. Re:why? by Anonymous Coward · · Score: 0

      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?

      To infinity and beyond?

    80. Re: why? by Anonymous Coward · · Score: 0

      Exceptions are just goto with clutter.

    81. Re:why? by BitZtream · · Score: 1

      None!

      But then, I'm a programmer rather than some guy who learned about goto in his coursework.

      --
      Persistent Volume manager for Kubernetes - https://github.com/dwimsey/openshift-pvmanager
    82. Re:why? by Anonymous Coward · · Score: 0

      Well written code is correct, understandable and efficient. You will find that the most efficient way to do something is quite often also the most sensible thing to do it.

    83. Re:why? by subanark · · Score: 1

      Fortunately in Java you can write this without needing goto (Java disallows goto, for the reasons that is was harmful). So it seems like goto is needed due to a language limitation.
      public int doSomeWork(Context context, int x) throws SomeException {
      int rv = 0;
      Database db = context.getDb();
      //Do some work ...
      Data v = context.copmute();
      MoreWork:
      {
      //Do some more work
      if(v == null) {
      break MoreWork;
      }
      //Do even more work
      }
      return rv;
      }

    84. Re:why? by Dutch+Gun · · Score: 2

      The most common one I see, people can't quite bring themselves to "return" from an error handler in the middle of a function, so they instead GOTO the end of it.

      I'd bet this is because of another slavishly followed idiom, which is that it's considered a bad practice to return early from functions. I'd guess that argument gets made because it's easy to miss the fact that the function is returning early, and thus accidentally leak a resource that was allocated earlier. While this is a good principle in general, it's always important to understand there are good exceptions for most any rules or idioms.

      Generally speaking, I tend to use early returns exclusively for error conditions (when writing or interfacing with C code, for instance) - for anything else, I try not to break the flow of the function. If it's complex enough to need early returns, then it's probably time to break things up into another function.

      As for GOTOs, I very, very rarely use them (if ever). There are almost always reasonable alternatives in which you can avoid them. That being said, I really have no problem with the very common idiom of a GOTO for errors ending at a label at the end of a C function for common resource cleanup. It's a pattern that any moderately experienced programmer would look at and understand completely at a glance.

      Of course, if someone was using that idiom in C++ code (when not interfacing with C code at least), then I'd have a chat with the programmer responsible to find out why they did that.

      --
      Irony: Agile development has too much intertia to be abandoned now.
    85. Re:why? by Anonymous Coward · · Score: 0

      Because it's impossible to do cleanup at "out" label?
      It was just an example.

    86. Re:why? by BronsCon · · Score: 0

      Such indentation is important

      and irrelevant to this discussion.

      --
      APK quotes people (including myself) without context and should not be trusted. Just thought you should know.
    87. Re:why? by perpenso · · Score: 1

      Some programmers take this idea to an extreme and even write code such as:

      int abs(int x) {
      int retval;
      if (x >= 0) retval = x;
      else retval = -x;
      return retval;
      }


      In this case, multiple return statements would make the code simpler, not harder to understand.

      Removing one line of source code does not necessarily make code simpler and more understandable, it merely make the source code shorter. It is only more understandable when the shorter code is acting in the default / more common manner. And for functions the more common manner is a single return at the end. So while quite readable because of its brevity it is doing the less common thing and therefore requires a little more cognitive processing while reading.

      Now in addition to being more readable with that one extra line, the common exit point, there is also the advantage of breakpoints when debugging. Now I am speaking in general and you may argue that in this specific case abs() is unlikely to need a breakpoint. If so I will counter that the function should still have a single exit point, as in:

      int abs(int x) {
      return (x >= 0) x : -x;
      }


      In all three implementations discussed it doesn't really matter what the source looks like beyond readability, the compiler will likely generate the same code.

    88. Re:why? by Anonymous Coward · · Score: 0

      "Bailing out" would have been "return rv" instead of the goto. The goto goes to the end of the function where you *clean up* things before you return. This is much better than having potentially multiple bailing-out points that all have to repeat the clean-up code.

    89. Re:why? by BronsCon · · Score: 1

      You're replying to someone who's never coded in C and, therefore, does not understand what you're talking about. Don't bother.

      --
      APK quotes people (including myself) without context and should not be trusted. Just thought you should know.
    90. Re:why? by Anonymous Coward · · Score: 0

      There is an alternative construct, which I consider much safer:

      static int
      do_some_work (context_t context,
                                  int x,
                                  error_t **error)
      {
              int rv = 0;
              database_t *db;
              data_t v;

              do
              {
                      db = get_db (context, error);
                      if (db == NULL) break; /* do some work ...*/

                      v = compute_v (context, db, error);
                      if (!v) break;

                      more work ...
              } while(0);

              return rv;
      }

      Reason being: Break can ONLY go forwards, and only up one scope, making it very hard to abuse
      Goto can go backwards, and into an entirely different scope. Even if *you* use it properly, the junior developer who just read your code may not use it properly.

    91. Re:why? by diamondmagic · · Score: 2

      You'd better post some better examples ASAP and back up your rationale, because you're empty assertions aren't winning over any new friends and your anecdotes don't seem to be very typical.

      As it stands now, goto is a perfectly legitimate way of breaking out of loops and skipping to cleanup after an error, without the necessity of bringing in (n+1) nested `if` blocks, and unreadability and unmaintainability that comes with it.

    92. 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.

    93. Re:why? by hattable · · Score: 1

      ALL OF THEM!

      --
      OMG facts!
    94. Re:why? by perpenso · · Score: 1

      Such indentation is important

      and irrelevant to this discussion.

      No. The indentation is evidence that the original goto advocate did not think carefully before breaking the rule since the coding style fails at its stated intent.

    95. Re:why? by Anonymous Coward · · Score: 0

      We can assume you're not using else statements because then goto would skip them, so the solution is no nested if blocks. Invert your if checks and you'll no longer need to nest them:

      if (check()) {
          doSomething();
          if (check2()) {
              doSomething2();
              return goodValue;
          }
      }
      return badValue;

      vs

      if(!check()) { return badValue; }
      doSomething();
      if(!check2()) {return badValue; }
      doSomething2();
      return goodValue;

    96. Re:why? by angel'o'sphere · · Score: 1

      Yeah, that is not a pattern but an anti pattern.

      The point where you used the goto you should have written 'return rv;'

      If you want examples for gotos then bring better ones.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    97. Re:why? by angel'o'sphere · · Score: 1

      Depends on the language.
      In Java break can break out of more than one loop, for that we have lables and 'break #label' as the syntax.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    98. Re:why? by AuMatar · · Score: 1

      That's a great way to ensure your code will never perform well. Architectural and algorithmic based performance issue need to be solved at the same time as correctness and understandability, or you'll never achieve it. There's levels of micro-optimizations that can wait, but people stating this kind of shit as a rule are fucking inconmpetent.

      --
      I still have more fans than freaks. WTF is wrong with you people?
    99. Re:why? by angel'o'sphere · · Score: 1

      No, the indentation, or lack therof is an indication, a stromg one even, that YOU are an idiot.

      The parent posted a quick example of some uncomplete C code in a forum, like /. and has to fiddle with tags and what ever to format it properly and you believe he intentionally indentated it 'wrong'?

      That makes you an idiot. Why don't you simlly asume the most likely cause is an formatting error?

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    100. Re: why? by Anonymous Coward · · Score: 0

      No, it is not. Check misra 2012

    101. Re:why? by Anonymous Coward · · Score: 0

      Really? You loose point for what is really the most sane way to handle cleanup in C? Have the instructors in those courses actually done any real work outside of academia? This is a very common pattern that I've seen in almost every large C code base that I've worked on.

      static int
      do_some_work (context_t context,

                    int x,

                    error_t **error)
      {

          int rv = 0;

          database_t *db;

          data_t v;


          db = get_db (context, error);


          do some work ...


          v = compute_v (context, db, error);

          if (!v)

              goto out;


          more work ...

      out:

          return rv;
      }

      It makes it so much cleaner and easier to read.

      I dont understand why this is preferable / more readable than

      if(v){

      do more work

      }
      return rv;

    102. Re:why? by firewrought · · Score: 1

      Why is it there, then? If operator overloading is only useful for mathematical constructions, why not simply bake those things into the language and be done with it rather than provide operator overloading which can, amongst other things, also be used to build those libraries?

      1. Building large math API's aren't a priority for language designers.
      2. To do what you're saying, you sort of have to add the operator overloading ability anyway, use it to implement a large math API, and then make the compiler "magically" treat that one API as special. If I were designing a language, I would rather--for both stylistic and practical reasons--just make a thumbs up/down decision on the overloading feature and let the community/marketplace develop their own math libraries.
      3. Note that the implementation of a mathematical concept can vary widely. A stock matrix implementation isn't going to be suitable for dealing with huge sparse arrays, for instance. Other implementations may want to use OpenCL/CUDA, decimal math, specific rounding policies... the list is endless.
      4. As others have pointed, there is a large range of mathematical ideas to which standard operators apply. Moreover, new maths are being added all the time and it's not unfathomable to invent your own idea to deal with a specific problem domain. (I've done this in production code, for instance, to enable set-like behavior of time-series data that is highly specific to the industry I work in. To be fair, I decided against operator overloading in that particular situation, but it could have gone either way.)
      5. These days, there's no real harm in providing the feature. Yeah, it was abused back when C++ was new, but developers got over that. When word processors were new, we all went silly and put 10+ different fonts into our documents, but you don't see that anymore either.
      --
      -1, Too Many Layers Of Abstraction
    103. Re:why? by abelenky17 · · Score: 1

      The Right Way is this:

      bool SomeFunc(void)
      {
              bool success;
              do
              {
                      success = DoStep1();
                      if (!success) break;

                      success = DoStep2();
                      if (!success) break;

                      success = DoStep3();
                      if (!success) break;
              } while(0);

              if (!success) /* Do Cleanup */

              return success;
      }

      This is "better" because break will only leave a single scope, and only go forward.
      With goto, you could go anywhere, leave any scope, enter any scope... and even go backwards.

    104. Re:why? by Richy_T · · Score: 1

      Not even just for error conditions. I think something like "if(x==NULL)return EMPTYSTRING;" at the beginning of a function for special case handling is very readable.

    105. Re:why? by perpenso · · Score: 1

      No, the indentation, or lack therof is an indication, a stromg one even, that YOU are an idiot. The parent posted a quick example of some uncomplete C code in a forum, like /. and has to fiddle with tags and what ever to format it properly and you believe he intentionally indentated it 'wrong'? That makes you an idiot. Why don't you simlly asume the most likely cause is an formatting error?

      The indentation I am referring to is not the indentation of comments in a discussion forum, look at my code samples in other responses in this topic. I don't bother with indentation either.

      What I am referring to is the normal indentation of the body of an IF statement in source code. The use of goto causes the conditional part of the code to not be indented, it appears inline with the header code. Read the periods in the following code as spaces:

      if (cond) {
      ....[body]
      }

      if (! cond) goto bailout:
      [body]
      bailout:


      Before tossing the word "idiot" around you might want to make sure you understand what is being discussed.

    106. Re:why? by Darinbob · · Score: 1

      Goto is a very useful construct. But because of your item #1 that you list, most people have been trained that the worst thing you can ever possibly do when programming is to use a goto. It is a taboo to a lot of people, essentially a superstition. They're not considering the pros and cons in a particular use case and instead reject it utterly without thinking.

      Too many times the only way to refactor the code to get rid of gotos is to add extra state variables or extra leaf functions.

      Granted some languages make it even easier to avoid goto, such as C++ with destructors doing the cleanup with automatic variables. But in C you don't have that, so often it is much cleaner and the code is easier to understand to just goto the end where clean up is done. Restructuring the code to avoid that will very often make things harder to understand.

      Now the worst of course I think is the programmer who avoids goto at all costs who also insists on only a single return from a function. I've seen some bizarre code written that way.

    107. Re:why? by barbariccow · · Score: 1

      Here's a better example I think:

      int something(void)

      {

      int x = 0;

      char *y, *z;

      int lock;

      int error; // stores error code, or 0 on success

      y = malloc...

      z = malloc...

      lock = get_lock()

      ... do work ...

      if(error) goto out;

      ... do work...

      if(error) goto out;

      ... do work...

      if(error) goto out;

      out:

      free(y);

      free(z);

      release_lock(lock);

      return error;

      }

    108. Re:why? by Darinbob · · Score: 2

      I'd quit before then. Sheesh, evaluate the code on its merits instead of dogma.

    109. Re:why? by barbariccow · · Score: 1

      The point is to not have to repeat freeing variables, releasing locks, etc everywhere. It's like a "finally" clause for people who cna only think in exceptions.

    110. Re:why? by brantondaveperson · · Score: 1

      Unfortunately the truth is that overloaded operators are a bad idea

      That's a really silly position to take. Operator overloads are incredibly useful, and are one of the things that really helps to make a language more expressive. They can be abused, but so can any part of any language, and taking them out because once you saw someone do something bad with them was an overreaction. And you can't seriously imagine that it's even remotely possible to provide built-in language support for mathematical operations on all possible mathematical objects.

    111. Re:why? by caseih · · Score: 1

      Okay, so as an exercise to the reader, add that cleanup code to the example. Now do you understand?

      In languages without goto or some other kind of construct such as a context manager, every time you want to return from a function you have to clean up all the threads, release memory, release handles, etc. This is error-prone (a prime source of leaks), and is wasteful and leads to difficult-to-read code. Whereas if you have a cleanup section that you can jump to, then every exit from the function goes to one place where the cleanup is properly executed. Hope this makes it clearer. As the article states, this is a very common idiom in C. Every good C programmer does this, and it's all throughout the Linux kernel. Sure if there were good, standard facilities for doing context management or a way of doing atexit handling for individual functions it would not be necessary, and maybe cleaner.

      But if you're familiar with the concept, when you see it in the code you understand exactly what's going on.

    112. Re:why? by angel'o'sphere · · Score: 1

      Hwo should the compiler know how to compile

      Point p;
      Something s;

      WhatIs w = p + s;

      If the operator + is not defined/overloaded by the user? How should the compiler 'invent' the type WhatIs?

      How a sane person can come to the idea that operator overloading is 'bad' is beyond me.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    113. 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.

    114. Re:why? by Richy_T · · Score: 1

      The difference is that it's immediately obvious what a return statement is doing whereas the goto puts the flow of code "elsewhere" and might be leaving things in a weird state (granted that the OP has since claimed he intended to put some cleanup code before his return which could change the circumstances).

    115. Re:why? by angel'o'sphere · · Score: 2

      Yes, he should when he needs it.

      Why should a programmer use different notations as a methematician would?

      Why should I be forced to read the doku of a rarely used math library to figure out what stupid abreviated function names the coder used, instead of using + and - as used in the MathML snapshot in my Word Document the companies chief mathematitian gave me as specc?

      Sorry, human beings invented mathematical notations. Other human beings invented programming. Most human beings proficient in both, want to use the same notations in both.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    116. Re:why? by Dutch+Gun · · Score: 1

      Well, naturally, a goto makes no sense if you only need to return a constant. To clarify, a goto (or similar jump construct) typically only makes sense in error conditions where you have a lot of common cleanup code AND when you have a number of sequential error checks, often return values from functions, that must be called in sequence.

      You don't want to have to repeat that cleanup code after each error check. So, assuming you don't want a horrendous nest of if/else conditions, you can either use goto error, or you can perhaps use an empty for statement and break-on-error to achieve the same sort of effect.

      In either case, unnecessarily duplicating the cleanup code is, in my opinion, a far worse offense than a goto or slightly non-standard for/break use.

      --
      Irony: Agile development has too much intertia to be abandoned now.
    117. Re:why? by Richy_T · · Score: 1

      Those operators are merely symbols that represent a subset of things they can do in the "real world". Why not allow them to represent a bigger subset of those things that they can do in the real world?

    118. Re:why? by TapeCutter · · Score: 1

      I've seen that style before, the "rule" is to only have one return statement per function, I think blindly following that rule produces ugly, convoluted, code, especially when it goes to maintenance mode where the rule will inevitably be broken. The problem in a nutshell is that it breaks the #1 coding commandment - As simple as possible, but no simpler.

      --
      And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
    119. Re:why? by Anonymous Coward · · Score: 0

      Sound good. Let us know when you've got a list of all the possible constructs where + might be an arithmetically meaningful symbol.

    120. Re: why? by TapeCutter · · Score: 1

      In the given example a 'return' in place of the 'goto' is more efficient (one less JMP), it's also less reading for others who might come after you. The "one return statement per function" style is not 'wrong' but it's more appropriate in assembly code than it is in higher level languages. Multiple returns in an assembly routine can be hard to see when reading since assembly is not typically indented, so the reader loses a valuable hint to the flow of the code. Doing the same thing in C/C++ typically just introduces unnecessary jumps for both the CPU and the human reader.

      --
      And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
    121. Re:why? by bytesex · · Score: 1

      I use a standard for coding in C that *requires* the use of goto. It goes like this:

      #define CHECK(fnc) { int __r = (fnc); if (__r) goto CLEANUP; }

      Then define each function to have a CLEANUP: label, and surround the call of every function from within this function by CHECK(). The CLEANUP label usually has a return 0; just before it, and in most cases a return nonzero; after it. Gives you clean code that always eats up the stack in case of error.

      --
      Religion is what happens when nature strikes and groupthink goes wrong.
    122. Re:why? by jonwil · · Score: 1

      I have a fairly large C++ project with a bunch of classes and it makes good use of operator overloading including overloading + and += on string classes, [] on containers and a whole bunch of operators on various kinds of matrices and vectors and stuff.

      Our codebase would be much less readable and easy to work with if it wasn't for operator overloading.

    123. Re:why? by Anonymous Coward · · Score: 0

      Almost certainly.

      I was a maintenance programme for a year or so in the mid-70s; there was still a ton of spaghetti code around and, trust me, those programmers were NOT restricting themselves to using goto safely or wisely.

      And don't get me started on the COBOL ALTER statement...

    124. Re:why? by tepples · · Score: 1

      Now consider the case where check1() and check2() allocate some resource, and you want to deallocate those resources before returning to the caller. In what practical way would goto deallocate_resources_and_return; be unclear?

    125. Re: why? by HornWumpus · · Score: 1

      In the example posted by the AC the goto and label saved one matched set of brackets and cost a 'not'.

      What it cost was the ability to find all conditionals related to a bit of code by finding the { (and hopefully the indent).

      The original AC even missed the point of his argument. If you have only one error condition the goto method is clearly worse.

      Most would argue that with multiple error conditions the goto solution is even worse. Now you have multiple conditionals that you can't see by quick scanning the source.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    126. Re:why? by Anonymous Coward · · Score: 0

      Even better was the ability in PL/1 for indexed gotos, so that you could do something like:

      if then
            goto Fail(1); .....
      if then
              goto Fail (2);

      etc...

      Fail(2):
            undo what was done between first two tests

      Fail(1):
          undo what was done before first test

      return;

      (My PL/1 is somewhat rusty, I haven't actually coded any in over 25 years).

    127. Re:why? by AmiMoJo · · Score: 1

      It wasn't a good example. The idea is that the exit code is more than just a return, as the comment hinted at it does some clean up. Checks if threads have started and aborts them, frees any allocated memory etc. It's a good model... er, pattern as the kids say.

      --
      const int one = 65536; (Silvermoon, Texture.cs)
      SJW, n: "Someone I don't like, and by the way I'm a fuckwit" - AC
    128. Re:why? by HornWumpus · · Score: 1

      Bullshit.

      Complex code is more difficult to understand. But code that has brackets and indents on all flow control is much _easier_ to read.

      Your looking at a line of code, it isn't running. Structured code makes it easy to find all the code that controls if the program got to that line and how often.

      Linearizing code that is not linear is exactly why you don't use goto.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    129. Re:why? by UnderCoverPenguin · · Score: 4, Interesting

      While I agree that certain constructs, like "goto" should not be used, I will point out that the full title of the 2004 version of the MISRA C document is:

      MISRA C:2004 Guidelines for the use of the C language in critical systems

      Note the word "Guidelines".

      Also note section 4.3.2, which discusses deviation procedures. In summary, it recognizes that full compliance is not always practical. And when deviations are made, they must be documented, justified and reviewed. Sometimes, such reviews involve showing 2 versions of the code in question: One without the deviation and the other with, so that the relative risks can be analyzed and discussed. Sometimes this process can result in an alternative with either a "less serious" deviation or no deviation. And sometimes the deviations are approved as-is.

      At the consulting company I work for, how strictly the various guidelines (not just MISRA, as only a few of our clients are automotive) deviations are approved depend on the customer. We certainly make great effort to only deviate from the various guidelines when the risks of compliance outweigh the risks of non-compliance. Sometimes business considerations override engineering considerations.

      --
      Don't try to out wierd me, three-eyes. I get stranger things than you, free with my breakfast cereal. --Zaphod Beeblebr
    130. Re:why? by TapeCutter · · Score: 1

      Yes there are rare scenarios where the style has it's uses in C/C++ but the example given is not one of them, a simple return would suffice and be easier to follow. Very deep nesting is the only scenario where I would contemplate using this assembly language style in a high level language, but deep nesting is often a symptom of poorly designed data structures.

      --
      And did you exchange a walk on part in the war for a lead role in a cage? - Pink Floyd.
    131. Re:why? by UnderCoverPenguin · · Score: 3, Interesting

      And how would you write acquireResources?

      --
      Don't try to out wierd me, three-eyes. I get stranger things than you, free with my breakfast cereal. --Zaphod Beeblebr
    132. Re:why? by HornWumpus · · Score: 1

      Look at his posting history and save your time.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    133. Re:why? by Darinbob · · Score: 1

      There are ways to avoid this in some languages. Ie, in C++ you can handle the cleanup on return in a nice way, releasing semaphores and memory automatically, using exceptions where allowed (sometimes can't use these in embedded systems). In C no such luck. The lower the level of the language the more likely it is to sometimes want to use low level constructs.

    134. Re:why? by fahrbot-bot · · Score: 1

      My typing and proofreading skills are often inadequate.

      --
      It must have been something you assimilated. . . .
    135. Re:why? by HornWumpus · · Score: 1

      You don't understand why brackets and indents on flow control are good.

      Until you get that you will continue to be wrong.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    136. Re:why? by Jane+Q.+Public · · Score: 1

      Also, depending on the language, using goto to break out of nested loops can lead to stack overflow.

    137. Re:why? by Anonymous Coward · · Score: 0

      Well, I'm not that guy, and I haven't worked in pure C for a while, but I don't understand why there isn't just a direct return statement. If there is further massaging of the data that is common to all return paths, I'd think another function would be the best way to go.

      (After all, "do some work" is probably going to be what, 10-20 lines or more? And then if you have enough different return paths that you care about such a thing, it's probably 4-5 different ones? And then your massaging if it isn't trivial is probably another 10-20 lines? Just get yourself another function by the time it's that long. Maybe I've been stuck in academics too long, though.)

      That said, I forget that gotos even exist today; the goto statements from ages past are evil evil things that are impossible to figure out without pencil and paper and a few hours to spare; and most likely the goto never turned into the real terror it was feared because a generation of programmers was taught from the beginning to not use the damn thing.

    138. Re: why? by Darinbob · · Score: 1

      Not even exceptions, I think that the vast majority of these gotos are a jump to the cleanup code. So having code that automatically executes on function return, like with C++ destructors on auto variables, would solve the problem.

      The snag with exceptions is that with many embedded systems they may take too much overhead.

      I definitely "avoid" the goto myself, and I think the branch to end of function style gets used far too much at work. However I have run across some cases where it's cleanest way to handle things. Ie, five resources are acquired with computation occuring between each acquisition, any of which could fail and need cleaning up. To split that into nested functions is clumsy, or to add an extra "abort" variable to skip all subsequent code. In C++ it's trivial to handle as you can return or throw an exception and let the destructor clean up things.

    139. Re:why? by Darinbob · · Score: 1

      I think the indentation is evidence that it's very difficult to make code look good in Slashdot. Especially a quick off-the-cuff code example meant to illustrate a point.

    140. Re:why? by QuasiEvil · · Score: 1

      Don't worry, after the parent poster fires you, come work for me. I'm of the same opinion you are - it's often the easiest and cleanest way to run a block of cleanup code. Plus, it doesn't create a crapton of nested functions and conditional tests, which can be a real issue in space-constrained platforms (8 bit micros, anyone?) I like people who aren't afraid of things they've been told are "bad" without at least considering if they have a possible use, and what the real dangers are. Sure, I'd expect there to be more than "return rv" in there, otherwise you should just be throwing returns in your main code, but still...

    141. Re:why? by kenaaker · · Score: 1
      Of course I understand. Mostly from having to debug and fix some of the multitude of ways that sort of "pattern" gets bollixed up. The biggest source of bugs in that instances of that pattern is the disconnect between the statements preceding each goto and the statements after the label. Do you have multiple labels? A label for each potential failing resource? An unwound set of labels? What convention are you using for the labels?

      Or, the another possibility is recording everything that needs to be cleaned up. That introduces more state data that has to be initialized, maintained in a coherent state and cleaned up.

      Now suppose that you have to change the order of setup because of a newly discovered hardware restriction. You potentially have to re-order the labels for your gotos, or which cleanup gets done after each label.

      If the cleanup is done at the bottom of every block that is executed because of success, it is automatically done in the proper time and place.

    142. Re:why? by Darinbob · · Score: 1

      Sometimes you can't afford that. Ie, I'm working on a chip with extremely limited memory. We run out long before the project is working well enough for even a demo, so we must start optimizing for space before it's correct or understandable. There are other cases I've had in the past where a real time deadline can't be met without doing some optimization (which generally means stop coding the naive way).

      If you *know* you're in the inner loop then why postpone writing code that is more efficient than the naive method since you *know* the optimization will be needed? Too often once the code is finished for "correctness and understandability" then the project ships and no time is given for "optimizing". Which can sometimes mean that a few months later management is in a panic because customers are complaining about how slow everything is.

      "Don't prematurely optimize" is another one of those proverbs that people worship without thinking about it. Not optimizing prematurely means doing a linear search through an array instead of using a built in function or data structure that is more efficient. Yes, in some places the linear search is appropriate as the code is not called often. But using a mapping data structure can speed things up and even use less coding and design time. I have run across a case where there were three linear searches nested within each other and for the end user the delay was noticeable and annoying, and caught the attention of the system administrator for excessive use of some system calls. The inner most loop in that case was something that the author would have known was a very critical function and should have spent minimal time thinking about the design instead of plopping in a naive solution.

    143. Re:why? by Darinbob · · Score: 1

      A "break" is technically a goto. Some people refuse to even allow a break in anything other than a switch statement.

      But if you get past that then this style is very appropriate to use. For some reason I see this being used very rarely even though the concept is straight forward.

    144. Re:why? by Capt.Albatross · · Score: 1

      Is that because they were warned by Djikstra that it would be harmful to use it haphazardly?

      Yes - at the time he wrote his paper, and for some time afterwards, goto statements were being used in a truly harmful manner.

      As you are probably aware, however, the marginalization of the goto did not guarantee clarity in programs. The confused have proven remarkably adept in finding other ways to sow confusion.

    145. Re:why? by angel'o'sphere · · Score: 2

      That is extremely unlikely.
      At the end you reach a 'return' which is translated more or less to an assembly 'rts' statement which takes care of cleaning up the stack.

      But perhaps you mean a goto that skips over function boarders? Not sure if you can do that in C and C++, if you can do that ofc. the stack is in your hands :) and you are at mercy of its limits.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    146. Re:why? by istartedi · · Score: 1

      Ditto. Any significant C I've written had "cleanup:" at the end of many functions, and "goto cleanup" wherever you had to bail out of the middle of such functions. Once I got over the "never use goto" mentality that was drilled into my head, I realized it was the most maintainable way of dealing with things that had to be released such as file handles, graphics contexts, memory, etc. Anybody who analyzed my code should have quickly picked up on the fact that this was an idiom for something like destructors in a language that doesn't have them.

      --
      For all intensive purposes, "whom" is no longer a word. That begs the question, "who cares"?
    147. Re:why? by angel'o'sphere · · Score: 1

      Looking at your code example, I have to admit I don't understand what you are talking about.

      Both code examples you gave have nothing to do with indentation and both are perfectly fine for me.

      Did you want to indent 'body' in your second example?

      As far as I can tell you are nitpicking about someones lack of skill to indnet properly in a forum. Which has nothing to do with his code how it might look in an editor.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    148. Re:why? by perpenso · · Score: 1

      I think the indentation is evidence that it's very difficult to make code look good in Slashdot. Especially a quick off-the-cuff code example meant to illustrate a point.

      The indentation I'm referring to is not the post's indentation. I don't bother with indenting code in posts either. What I am referring to is the normal source code indentation that appear in the body of an if statement. In the alternative goto scenario this conditional block appear inline with the header code in the source. Read the periods in the following code as spaces:

      [header]
      if (cond) {
      ....[body]
      }

      [header]
      if (! cond) goto bailout:
      [body]
      bailout:

    149. Re:why? by puzzled_decoy · · Score: 1

      Maybe I'm missing something here but why not... bool success = true;
      success =
      doSomethingThatMightFail() &&
      doSomethingElseThatMightfail() &&
      doMoreFailingStuff() &&
      yepMoreFailingStuff();

      if (!success) {
      cleanupWork
      }

    150. Re: why? by Anonymous Coward · · Score: 0

      I guess you assumed yourself an expert when you didn't program properly in C then.

    151. Re:why? by Anonymous Coward · · Score: 0

      1968 was the year Djikstra wrote his article. At that time, arguably the dominant languages (FORTRAN IV and...

      I would think Fortran 66, no? (Sadly, I still have to deal with some of that. Which is to say, it looks like fixed form Fortran, but it won't compile on anything modern without modification because today no one goes before Fortran 77, but that standard prohibited a few things which were common before.)

      Also, goto/continue statements back then? I have a PhD, my days are spent coding (i.e., you can call me an idiot if you want, but I'm not completely dense), and a simple 10-20 line pile of gotos of the day can take me over an hour with pen and paper to sort out.

    152. Re: why? by smaddox · · Score: 1

      Correction: break can't break out of two loops in many popular languages.

    153. Re:why? by edtice1559 · · Score: 1

      This may be a good solution but only due to other limitations of the language. What you are really doing here is implementing the equivalent of a "finally" clause as is available in Java, .Net, and other languages. Indeed if you called your label "finally" instead of "out," it would be pretty clear what you are doing. I'm not saying that the goto here is bad, but rather that the need for it works around a language design issue.

    154. Re:why? by Anonymous Coward · · Score: 0

      Everyone stop and LRN2SLASHDOT!

      if (cond) {
          [body]
      }

      I won't tell you how to do this because just about every single person in this thread is a fucking knob.

    155. Re: why? by Anonymous Coward · · Score: 0

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

      People who trot out this drivel need to be shot. It doesn't matter what the compiled code looks like (as long as it's efficient enough for its purpose). The compiled code doesn't need to be maintained, and the arguments against goto are all about maintainability.

      (Note that that doesn't say anything about whether goto is appropriate in the situation under discussion, just that arguing based on what the compiler output looks like is bullshit.)

    156. Re:why? by puzzled_decoy · · Score: 1

      Maybe I'm missing something here but why not...

      bool success = true;
      success =
      doSomethingThatMightFail() &&
      doSomethingElseThatMightfail() &&
      doMoreFailingStuff() &&
      yepMoreFailingStuff();

      if (!success) {
      cleanupWork
      }

    157. Re:why? by AaronW · · Score: 1

      There is a time and place to use goto. It works well for handling error cases and can lead to better code.

      Instead of:

      rc = some_function()
      if (rc) {
        do lots of cleanup of earlier stuff()
        return rc;
      }

      rc = some_other_function()
      if (rc) {
        do even more cleanup()
        return rc;
      }

      I can just use:

      rc = some_function();
      if (rc)
          goto error_handler; ...
      error_handler:
        perform any needed cleanup
        return rc;
      }

      The other method would be a huge nested mess of if/else conditions.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
    158. Re: why? by jschultz410 · · Score: 2

      The main reason to have a single exit point in C code is so that you can easily add exit invariant checks and/or logging or anything else you want whenever the function returns. If you have ten different returns sprinkled throughout a function you have to go and funge with all of them and convert them to the other form (i.e. - goto RETURN). Also, if you have goto error handling and cleanup code (which you almost always do anyway) you will naturally have a place for a single return point.

    159. Re:why? by AaronW · · Score: 1

      And that gets rather ugly if you have things inside loops and more complicated logic. It becomes far cleaner to just say:
      goto error_handler;

      break doesn't work so well when you have multiple levels of loops or other complex logic.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
    160. Re:why? by jschultz410 · · Score: 1

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

      You obviously do not write much C code. Almost every non-trivial function call in a C program can fail or function abnormally. Asserting that you can somehow magically not have error detection and handling in the main flow of your C code is ridiculous.

    161. Re:why? by AaronW · · Score: 1

      Indenting the flow can get bad if it starts to get rather deep. In my case, the code bases I work on use 8-character tabs for indenting and also limit the code to 80 columns. It quickly grows difficult to read and maintain if you have to keep indenting when a simple goto error_handler is far easier to deal with and I have found less error prone and easier to read. The flow remains easy to read since the error handler is always at the end of the function.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
    162. Re:why? by bidule · · Score: 1

      if ! (doSomethingThatMightFail() &&
        doSomethingElseThatMightfail() &&
        doMoreFailingStuff() &&
        yepMoreFailingStuff()) {
          cleanupWork();
      }

      OR

      do {
        if ! doSomethingThatMightFail() break;
        if ! doSomethingElseThatMightfail() break;
        if ! doMoreFailingStuff() break;
        if ! yepMoreFailingStuff() break;
      } while (false);

      Utterly tongue in cheek!

      --
      ID: the nose did not occur naturally, how would we wear glasses otherwise? (apologies to Voltaire)
    163. Re:why? by beelsebob · · Score: 1

      Because then when one thing fails, the following things still execute, but now in a bogus state.

    164. Re:why? by beelsebob · · Score: 1

      Okay then oh wise one. Explain to me why brackets, indentation and control flow is good in the above example? Why is the CHK control flow structure (one that effectively mirrors what the error monad does, but is a little lower level due to C) less a valid control flow structure than the nested ifs?

    165. Re:why? by beelsebob · · Score: 1

      Which is exactly what this paper addresses. It turns out that the *actual* uses of goto in real world C code involve cases where it's immediately obvious where you're going to, like error handling code that just does a goto cleanup.

    166. Re:why? by beelsebob · · Score: 1

      What you're saying is "I'm afraid of the word goto, so you should write code with the exact same semantics as the goto based code, but with different words that imply different semantics".

      I mean really, this code is just using goto, but renaming it do/while/break. It's not actually using the do/while abstraction for what it's for, it's simply abusing it to make goto.

      In the mean time, others have already addressed why this is less convenient than the goto pattern for error handling, so I don't really buy this as a reason not to use goto in the structured "I'm simulating the error monad" case.

    167. Re:why? by jschultz410 · · Score: 1

      Your code is actually an example of why you should use goto rather than another construct.

      I notice that you left the /* Do Cleanup */ part unimplemented. Now why didn't you fill that bit in if it's so easy? I'll tell you why: all your error breakouts jump to the same spot and so your cleanup code has to re-figure out exactly what does and doesn't need to be cleaned up somehow. Far better to simply encode that into the logic of the function itself:

      bool SomeFunc(void)
      {
          bool success;

          if (!(success = DoStep1()))
              goto FAIL;

          if (!(success = DoStep2()))
              goto FAIL_CLEANUP1;

          if (!(success = DoStep3()))
              goto FAIL_CLEANUP2;

          assert(success);
          goto END;

      /* error handling and return */

      FAIL_CLEANUP2:
          CleanUpStep2();

      FAIL_CLEANUP1:
          CleanUpStep1();

      FAIL:
          assert(!success);

      END:
          return success;
      }

      If your function only needed to temporarily grab the resources and release them all before returning then it is possible to cleanly do that using nested if's, although a lot of people find that style ugly and hard to read, especially if your coding standard calls for 4 space or 8 (!) space indentation per each nesting level.

    168. Re:why? by Anonymous Coward · · Score: 0

      This is nothing but a goto confusingly disguised as a loop. The "loop" surrounds the entire function and it isn't clear it really isn't a loop until you get to the WTF while(0) at the end. If you have to do error checking in a loop you're fucked because you can't break out of multiple loops. I've seen so many different ways of avoiding goto when doing error handling with return codes. Most of them are worse than just using goto, but "do {} while(0)" wins the coder special olympics gold medal.

    169. Re:why? by AaronW · · Score: 1

      A goto certainly makes cleanup code a lot easier, especially in my line of work on bootloaders, device drivers and other stuff. There are many cases where it is far cleaner to use a goto error_handler; in the code, especially if there are multiple locations and have all of the cleanup code in one place rather than duplicating it all over the place.

      There are other times when a goto can also make sense, for example if you have multiple nested levels of logic you want to get out of it in a hurry. It takes an experienced programmer to know when to use it and when not to. I have seen many cases where a single goto or using goto for error handling makes the flow of the code much easier to read and where it can significantly reduce the size of the code. That's not to say that it can't be abused either. I have also seen cases where it makes the code more difficult to read but in most cases where I come across it it simplifies the logic flow and helps keep the code from being cluttered.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
    170. Re:why? by AaronW · · Score: 1

      It also adds another useless level of indentation which can be a problem making the code difficult to read, especially in projects which follow the Linux kernel coding convention.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
    171. Re:why? by Anonymous Coward · · Score: 0

      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) { ...

      Why not write code like below and let the compiler do its job?

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

    172. Re:why? by perpenso · · Score: 1

      I have written a lot of code in my life - Thousands of projects, millions of lines of code (for whatever that means), across a dozen languages and twice as many platforms. And outside Assembly (and DOS batch, if you want to count that as a "language"), I have not ever encountered a situation where I thought to myself "gee, I could really improve this with a GOTO, if only everyone wouldn't laugh at me for it".

      I'm with you there.

      I have, however, removed some pretty heinous uses of GOTO from other people's code. The most common one I see, people can't quite bring themselves to "return" from an error handler in the middle of a function, so they instead GOTO the end of it. Really??? Talk about missing the forest for the trees!

      You are missing the forest of testing and debugging. :-) Its easier if you just have one place to set a breakpoint.

    173. Re:why? by beelsebob · · Score: 1

      Because often, this code is a lot more complex, involves loops, chunks of other simple statements in between etc. In general, the thing inside the "if (success)" can be substantially more complex, and end up needing nesting anyway.

    174. Re: why? by jschultz410 · · Score: 1

      I keep seeing people talking about using setjmp / longjmp to handle errors and cleanup, but I'm not familiar with that style and don't see how it solves the problem.

      With goto's you jump to exactly the cleanup code you need to release the resources that you have already acquired within the function -- usually in reverse order so that you are effectively doing what C++ block destructors would do automatically for you.

      setjmp / longjmp would let you return to a previous point in your code but wouldn't do anything for the actual necessary cleanup unless everything was on the stack right?

    175. Re:why? by jschultz410 · · Score: 1

      "Do you have multiple labels?"
      Yes.

      "A label for each potential failing resource?"
      Yes.

      "An unwound set of labels?"
      You reclaim the resources in the reverse order that you acquired them so that the error handling code is common to all the error goto's. Basically an explicit form of C++'s stack unwinding and deconstructor invocation.

      "What convention are you using for the labels?"
      I typically name the labels as FAIL_${last_successfully_acquired_resource_name}. For example, "goto FAIL_LOCK;" for a failure that occurs after acquiring a mutex named "lock".

    176. Re:why? by UnknownSoldier · · Score: 1

      Indeed, ANY language feature can be abused.

      Let's abuse whitespace! O_o

      Since /. formatting for code is SO fucked up that I can't even paste the source code, here's a link to it ..

        * https://gist.github.com/cgoldb...
        * http://www.perlmonks.org/?node...

    177. Re:why? by Anonymous Coward · · Score: 0

      And, the get_db acquired locks and did mallocs, compute_v created a new thread to handle something asynchronously.

      So, bailing out leaves dangling threads, leaking memory, and deadlocks that show up the next time the function is entered.

      It's the easy way out only once.

      Meh..

      if (v) {
              # do work
      } else {
              # cleanup
      }

    178. Re:why? by Anonymous Coward · · Score: 0

      Fortunately in Java you can write this without needing goto (Java disallows goto, for the reasons that is was harmful). So it seems like goto is needed due to a language limitation.


      public int doSomeWork(Context context, int x) throws SomeException {

            int rv = 0;

            Database db = context.getDb(); //Do some work ...

            Data v = context.copmute();

            if(v != null) { //Do even more work
            }
            return rv;
      }

      Why are all these examples trying to avoid doing work inside that conditional?
      If it's all that many lines, put a damned method in there.

    179. Re:why? by Anonymous Coward · · Score: 0

      In your example, there's absolutely no need for a goto....

      bool success = (doSomethingThatMightFail());
      if (success) success = doSomeThingElseThatMightFail(); ...
      if (!success) {
          cleanupWork();
      }

      There are a few times when GOTO is the only reasonable alternative, but I haven't ever seen one in the wild in 3 decades of programming in anything other than assembly.

      On a related note, I actually ran across a GOTO statement in a piece of Ada code on a DoD project; and yes, in that case there wasn't a good reason for it other than it was translated (poorly) from FORTRAN.

    180. Re:why? by Alomex · · Score: 1

      Most human beings proficient in both, want to use the same notations in both.

      Which is why C's choice of assignment operator is so asinine and bug inducing, yet one that few of its descendants has been willing to break. In fact I can only think of Go as a modern language which eschewed it.

    181. Re:why? by Alomex · · Score: 1

      ...and the one use of GOTO that could be often justified got incorporated into modern languages as the break/continue pair.

      So all in all a good outcome: stop using GOTO as the main control structure while preserving its good uses.

    182. Re: why? by ShanghaiBill · · Score: 1

      The main reason to have a single exit point in C code is so that you can easily add exit invariant checks and/or logging or anything else you want whenever the function returns.

      The proper design pattern for this is to move the invariant/logging code into a parent function. So instead of this:

      void foobar()
      {
        if (work1()) goto done;
        if (work2()) goto done;
        if(work3()) goto done; ....
      done:
            logSomething();
            return;
      }

      You do this:

      void do_work() {
            if (work1()) return;
            if (work2()) return;
            if (work3()) return; ....
      }

      void foobar()
      {
            do_work();
            logSomething();
            return;
      }

    183. Re:why? by Anonymous Coward · · Score: 0

      You have to be kidding.

      Instead of "goto out;" you could have just said "return rv;" and avoided the need to scroll through a bunch of non-relevant stuff.

      Your example isn't simpler. It is just barely more complicated than the much more typical early return.

    184. Re:why? by bunratty · · Score: 1

      Exactly! The multiple return statements make the code easier to understand. Some programmers are so militant about having a single return statement in every function that they can't tolerate that code, though.

      --
      What a fool believes, he sees, no wise man has the power to reason away.
    185. Re:why? by fahrbot-bot · · Score: 1

      Indeed, ANY language feature can be abused.

      Let's abuse whitespace! O_o

      You talk whitespace abuse and don't even mention Python - for shame. :-)

      --
      It must have been something you assimilated. . . .
    186. Re: why? by jschultz410 · · Score: 1

      Why make two functions when one suffices? Especially when you already have goto error handling that naturally gives you a good spot for a single exit point anyway (as all your error exits will go out the same way)?

    187. Re:why? by pla · · Score: 1

      Assuming we don't write this in a language with some variant of either "using" or "finally" syntax... You still have two alternatives in cases where you have cleanup that needs to occur unconditionally.

      The first (which I often opt for, myself) - Put it in the caller:
      foo = BuildUpFragileStatefulStuff();
      result = myEasilyBrokenHugeBlockOfConditions(foo);
      if(result==OhShit) {foo.unwind(); foo.cleanup(); foo.bar(); foo.close(); foo.dispose(); foo=null;}

      And the second, for when you have lot of cleanup - Put it in its own function:
      foo = BuildUpFragileStatefulStuff();
      ...
      if(ThisCondition==BadMojo) return(UnFuckify(foo));


      I really cannot think of a scenario where one of those leads to less clarity or more redundancy than replacing them with "Goto OhShit"

    188. Re:why? by _merlin · · Score: 1

      The clean C++ way to deal with that is to use RAII and have little helper objects that are there just for their destructors. It lets you return from any point in a function (or exit via an exception) and still have all your cleanup done. Of course it obfuscates flow even more than goto.

    189. Re:why? by Anonymous Coward · · Score: 0

      all conditional statements and loops are just a subset of goto.

      do {
      if ( !blah ) continue;
      switch ( something ) {
        case 1:
          if ( something ) continue;
          blah.blah();
          break;
        default:
          etc();
          break;
      }

      } while ( 0 );
      // continue is now a GOTO sans "forbidden" GOTO statement.

    190. Re:why? by Marillion · · Score: 1

      Exactly. I use gotos as part of exception handling. You need to bail out of a function, but you need to clean up first ... { goto cleanup; cleanup: free( whatever ); close( something ); }

      --
      This is a boring sig
    191. Re:why? by Imagix · · Score: 1

      Single entry/single exit code was a convention in order to combat the problem of developers attempting to write cleanup code in multiple places within a function. Which causes a maintenance issue as it makes it possible that one cleanup location gets updated and the other(s) get missed. Another solution is the concept of a destructor in C++ (or a similar concept in other languages) where one can put the cleanup code in one place that is guaranteed to be executed when the function exits regardless if is was a return or an exception. And I do agree.. blindly following any convention is bad. But one should use the convention with the understanding of why the convention exists.

    192. Re:why? by gnupun · · Score: 1

      If you worked for me, and you wrote garbage like that, I would give you a verbal warning and show you how to do it correctly.

      LOL. I worked on a project where we couldn't use C++, only C. I used the same goto pattern for cleanup. The alternative would've been a bunch of nested if statements and that would make the code less readable and difficult to maintain. Goto is the superior solution for exit-on-error scenarios.

      If this code pattern is garbage, can you show the alternative that is not garbage?

    193. Re: why? by spongman · · Score: 3, Informative

      Your post implies you don't know how the C && operator works...

    194. Re:why? by Anonymuous+Coward · · Score: 1

      3. Some compilers don't even try to optimize a function containing a goto.

      I call bullshit on this.

      As to your other points, don't forget that C doesn't have labeled loops, like java or perl.

      So no, "goto" is NOT easy to avoid, if you have to break out of an inner loop. The alternative (set a variable then test it on each iteration of each outer loop) is ugly, messy, inefficient and is obfuscating the program logic.

      Most people that pretend to avoid gotos are cheating by "refactoring" the resource freeing blocks into separate functions and then using multiple return paths, which is just as anti-Dijkstra as going full gotos everywhere.

    195. Re:why? by Anonymous Coward · · Score: 0

      Time for the meta-discussion:

      How can you tell the fool from the wise?

      The fool thinks he is wise. The wise thinks he is not wise.

    196. Re:why? by mark-t · · Score: 1

      It must really be nice to be be so independently wealthy that you can just choose to walk away from a job if you happen to disagree with your supervisors over matters of programming style.

      Obviously there are some philosophical differences that you might have with your supervisor that could justly warrant leaving your job, but such issues are generally less technical in nature and tend to tread more in the domain of being treated with respect and fairness.

      But if you are so inflexible in coding style that you are unwilling to adapt to whatever the person who pays your salary is going to expect, then you are probably going to have to be self employed, because I can't imagine that you'd be very happy in almost any other situation.

      Not that there's anything wrong with being self-employed but being self-employed requires maintaining a list of clients that are willing to pay you to get a job done, and not all people who might happen to be pretty darn good at programming have all of the social skills necessary to be able to successfully maintain such a list.

      You'll have to excuse me if I don't identify with your assertion. Doubtless, you would probably categorize me as a fool.

    197. Re:why? by angel'o'sphere · · Score: 1

      I would prefer something like this := too :)

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    198. Re:why? by Anonymous Coward · · Score: 0

      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.

      The point is that there are many other ways to arrive at the end without relying on GOTO, and in most situations if GOTO looks like it will be a good option then there's either a serious design problem, or you don't really understand what you are doing. Heinous if/else deep nestings are usually a result of a similar problem, or someone trying to lump far too much into a single routine.

      Frankly speaking, GOTO is a low-level option masquerading as a higher level command, and mixing the two is usually not a wise decision. If you really think you need to short-circuit the higher level language functionality with a GOTO then you're probably better off just dropping some inline assembly instead. The big issue with GOTO is not that it can't be used safely, but that it can be used by people who don't have a solid enough understanding to write the assembly... and that's a dangerous thing.

      Having said all that, I will admit there are times when I've had to rely on GOTO myself. But those times were either temporary debugging measures, or situations where I had to fix someone else's broken code with very little time and no option for a re-write.

    199. Re:why? by BetterThanCaesar · · Score: 1

      But perhaps you mean a goto that skips over function boarders? Not sure if you can do that in C and C++, if you can do that ofc. the stack is in your hands :) and you are at mercy of its limits.

      It's called setjmp and longjmp and has been a part of the C standard since C89. However, you can still only jump UP through the stack, i.e. to a calling function, to code that has already been run.

      #include <setjmp.h> /* C */
      #include <csetjmp> // C++

      See https://en.wikipedia.org/wiki/Setjmp.h for more information.

      --
      "Stop failing the Turing test!" -- Dilbert
    200. Re:why? by Anonymous Coward · · Score: 0

      I found Goto a lot easier to read than 20 layers of nested If statements. Essentially a situation where you have a pipeline of code doing one stage at a time, but you need it to immediately stop if any one of those stages did not work.

      There are other ways to do that besides goto or nested if's. You could implement that using the switch construct, only breaking out of each case in the event of a failure flag being set... just as one example.

      While I don't share most people's instant revulsion to GOTO, I have found that most of the time it's the equivalent of painting yourself into a corner and having to jump out a window... if you approach the problem from a different angle you can often avoid the situation entirely.

    201. Re:why? by Anonymous Coward · · Score: 0

      goto in a macro? are you serious?

    202. Re:why? by dgatwood · · Score: 1

      A better example:

      char *dosomething() {
      char *tempvar = malloc(...);
      char *tempvar2 = malloc(...);

      do something...

      if (some error occurs) {
      goto fail;
      }

      do something else...

      if (some error occurs) {
      goto fail;
      }
      ...
      free(tempvar2);
      return tempvar;

      fail:
      if (tempvar) free(tempvar);
      if (tempvar2) free(tempvar2);

      return NULL;
      }

      Basically, it works well when you have a significant amount of cleanup to do upon failure, because the alternative is writing half a dozen free/delete/release/CFRelease calls right before every return statement.

      --

      Check out my sci-fi/humor trilogy at PatriotsBooks.

    203. Re:why? by jandersen · · Score: 1

      How about:

      static int
      do_some_work (context_t context,
                                  int x,
                                  error_t **error)
      {
              int rv = 0;
              database_t *db;
              data_t v;

              db = get_db (context, error);

              do some work ...

              if (v = compute_v (context, db, error)){
                      more work ...
              }
              else
                      return rv;
      }

      To my eyes, the block structure makes it easier to see what goes on, and the goto is not used. In your example, the goto blends into the surrounding code, making it easy to overlook. Also, I think most people expect the TRUE outcome to be the one actioned upon, which is in fact what your example does as well.

    204. Re:why? by Anonymous Coward · · Score: 0


      static int do_some_work (context_t context, int x, error_t **error)
      {
          int rv = 0;
          database_t *db;
          data_t v;

          do
          {
            db = get_db (context, error);

            do some work ...

            v = compute_v (context, db, error);

            if (!v)
                break;

            more work ...

          }
          cleanup.....
          return rv;
      }

      yw.

    205. Re:why? by Anonymous Coward · · Score: 0

      was meant to be a do { } while(1); and have a break or return at the end of the loop. but yeah i suck at writing code in the text editor

    206. Re:why? by dgatwood · · Score: 1

      Your first approach is generally a very bad idea. The more copies you make of a block of code, the higher the probability that you'll miss one of them when you later have to modify that block of code. If you have more than about two statements that have to appear before every return statement, your odds of introducing bugs goes through the roof.

      Functions are an acceptable way to handle complex cleanup, but they don't really buy you anything over a goto, and if you're cleaning up a lot of variables, the argument list can become unmanageable.

      That's why the "goto fail" pattern is so common in kernel programming, where a single bug can be catastrophic.

      --

      Check out my sci-fi/humor trilogy at PatriotsBooks.

    207. Re:why? by Anonymous Coward · · Score: 0

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

      FTFY - no goto

    208. Re:why? by MadKeithV · · Score: 1

      There may be a better pattern, but in a few cases, I found Goto a lot easier to read than 20 layers of nested If statements..

      That's a straw-man argument: no-one would seriously argue that having 20 layers of nested conditionals is good code so even shops that religiously avoid goto would rewrite that code to something that doesn't suck.

    209. Re:why? by gl4ss · · Score: 1

      "Have the instructors in those courses actually done any real work outside of academia?"

      no.

      didn't stop them from writing the book on the subject though and forcing the students to by the book they authored and had printed, so I think they at least did a calculus course before that.. besides, the aim of the course is to try to teach people to program right(tm(C) by books author).

      besides than that, they would tell you to not use C but to use garbage collecting c++ or whatever extension of the year happens to be in vogue, getting around this cleanup problem(and moving it elsewhere).

      --
      world was created 5 seconds before this post as it is.
    210. Re:why? by angel'o'sphere · · Score: 1

      Yeah, we know that :)

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    211. Re:why? by fractoid · · Score: 1

      I've seen the structure you're describing in a DirectX tutorial (admittedly, back in DX3):

      if (!doFirstStage()) goto cleanup;
      if (!doSecondStage()) goto cleanup;
      ...
      if (!doTenthStage()) goto cleanup;
      printf("woohoo!\n");
      return true;

      cleanup:
      cleanupTenthStage();
      cleanupNinthStage();
      ...
      cleanupFirstStage();
      printf("bugger");
      return false;

      It was actually advised as best practice for initializing the stack of COM objects required to get DX up and running. It's certainly cleaner than:

      if (!doFirstStage()) {
      cleanupFirstStage();
      return;
      }

      if (!doSecondStage()) {
      cleanupSecondStage();
      cleanupFirstStage();
      return;
      }
      ...
      if (!doTenthStage()) {
      cleanupTenthStage();
      cleanupNinthStage();
      // ...
      return;
      }


      The RAII pattern makes this a lot simpler (at least in OO languages), but if you're sticking with C then this "goto failed;" is simpler and probably cleaner.

      --
      Rampant carbon sequestration destroyed the Dinosaurs' tropical paradise. I'm here to help repair the damage.
    212. Re:why? by fractoid · · Score: 1

      Exceptions make it easy to handle fault conditions badly, but no easier (and arguably harder) to handle fault conditions correctly. I was just reading this rant on Old New Thing today about this very subject. If nothing else, the amount of debate on "how to do this easy thing properly" should suggest that exceptions aren't a silver bullet.

      --
      Rampant carbon sequestration destroyed the Dinosaurs' tropical paradise. I'm here to help repair the damage.
    213. Re:why? by bingoUV · · Score: 1

      Same thing happens when you use functions. Is this a reason to not use functions?

      E.g.

      activity(){
          if(part1required){
              part1;
          }
      }

      Here, part1 is under if which is under activity(), so part1 is indented two levels lower than activity(). Later part1 becomes complicated, so we move it out in a function - funcpart1().

      activity(){
          if(part1required){
              funcpart1();
          }
      }
       
      funcpart1(){
          part1;
      }

      By using functions, part1 has come at just one level under activity(), even though logically it is 2 levels under activity().

      By using the functions, flow has changed, and in this new flow part1 is just one level under activity. Similarly, by using goto, flow changes and there is less indentation required in the new flow.

      --
      Bingo Dictionary - Pragmatist, n. A myopic idealist.
    214. Re:why? by Anonymous Coward · · Score: 0

      Only pendants are convinced the issue is black and white.

      Leave the jewelry out of this.

    215. Re:why? by pla · · Score: 1

      The more copies you make of a block of code, the higher the probability that you'll miss one of them when you later have to modify that block of code.

      Not sure what you mean by "copies" - In that example, you have only a single cleanup section, in the calling function rather than in the called function - You've basically split the problematic code into two pieces to let the stack itself unwind most of the problem naturally, rather than needing to jump around to various no-context error handling blocks.

    216. Re:why? by Anonymous Coward · · Score: 0

      I think you'll find that's "pedants".
      *ducks for cover*

    217. Re: why? by reanjr9417 · · Score: 1

      Just because you're afraid of multiple return statements does not make your goto easier to read.

    218. Re:why? by Richy_T · · Score: 1

      Yeah. I don't see it being abused too much. I avoid using it but I wouldn't have a huge problem if I saw it and it wasn't being abused terribly.

    219. Re:why? by Anonymous Coward · · Score: 0

      So it's used as a crutch in the absence of try ... catch ... finally language features?

    220. Re:why? by HornWumpus · · Score: 1

      Because you can't glance at the non indented code and see where the conditionals are. Duh.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    221. Re:why? by HornWumpus · · Score: 1

      Fair enough. We can make exceptions for those still using punched cards.

      --
      John McAfee 'It was like that time I hired that Bangkok prostitute; to do my taxes, while I fucked my accountant'
    222. Re:why? by Richy_T · · Score: 1

      I don't know. I think it's case dependent. In the example cited, the cleanup code is simple function calls and the operations are different for each case (for one, it's one cleanup, for another, it's two and for the success it's three).

      Part of the problem is, the examples are really too small to call either way. I try to aim for my code to be clean and understandable and not to be dogmatic about things. I avoid certain Perl idioms for just this reason. Though I certainly agree that TMTOWTDI

    223. Re:why? by Anonymous Coward · · Score: 0

      Uh huh, "break label"? Sure, within the same method, but to do a goto out of a procedure in C would be pretty stupid anyway.

      Oh wait, C is just shit isn't it? That, and try ... catch ... finally just not existing so people use goto instead.

      Simply put, other languages leave C in the dust, and it's only intertia and elitism that keeps it going.

    224. Re:why? by Anonymous Coward · · Score: 0

      The dislike of multiple return statements in a function is based on academic thinking, not reality.

      Indeed, especially as the same academics will fap all over functional languages that do this (pseudocode):

      fun x (y) :
            y = 0 : 0;
            y > 0: y + x ( y -1 );

    225. Re:why? by Anonymous Coward · · Score: 0

      Dijkstra should have written an essay on "#define considered bad" imo.

    226. Re: why? by ilsaloving · · Score: 1

      Are you an anti-vaxxer as well? Because you're using the same logic that they use.

      "It's not a problem anymore so we shouldn't have to do this and I resent being told what to do!"

      It's not a problem anymore BECAUSE avoiding goto has become conventional wisdom.

      If we start telling people that it's ok to use goto again, take a wild guess what will happen? We will go right back to the days of spaghetti code, except it will be that much worse now because software has become overwhelmingly more complex today compared to several decades ago.

      The problem with self-described experts is that a lot of people think they're experts when in fact they are not, resulting in a hideous mash that some poor sap down the line has to somehow decipher.

      It boils down to risk-reward. If there is a clear and overwhelming reason to use it, then go ahead. If not, then a convention control flow structure will be easier to debug, easier to maintain, and is less likely to cause an inadvertent bug because you jumped out of a code block without cleaning something up.

    227. Re:why? by Anonymous Coward · · Score: 0

      And this is why C programmers are considered hackers, and C is barely a language, more a shim above assembly.

      FFS, why hasn't some form of try / catch / finally been added to C99, C14 or whatever?

      Still, GOTO finally; .... finally: is the same. Just use the sane standard label for it if the language is so prehistoric it doesn't support structured programming at this level.

    228. Re:why? by Capt.Albatross · · Score: 1

      I didn't vote on it, but I guess it is due to the last paragraph. Compilers are just as capable of generating valid code from unstructured source as from structured source, so long as it is syntactically correct. It is humans who tend to get confused by unstructured code, not compilers.

      Which is not to say that structured code is necessarily free of confusion - I have seen plenty of counter-examples.

    229. Re:why? by Anonymous Coward · · Score: 0

      Point p;
      Direction s;
      MovingPoint w = p.withDirection(s);

      You don't need to overload operators in many cases when a more descriptive method name will suffice.

      However I do approve of operator overloading in general.

    230. Re:why? by Anonymous Coward · · Score: 0

      success = true;
      do {
              success = doSomethingThatMightFail();
              if ( ! success ) { break; }
              success = doSomethingElseThatMightFail();
              if ( ! success ) { break; }
              success = doMoreFailingStuff();
              if ( ! success ) { break; }
              success = yepMoreFailingStuff();
              if ( ! success ) { break; }
      } while ( 0 );
      if ( ! success ) {
              cleanupWork();
      }
      return success;

    231. Re:why? by hattig · · Score: 1

      In the post you hurried to reply to:

      In this case, multiple return statements would make the code simpler, not harder to understand.

    232. Re:why? by Capt.Albatross · · Score: 1

      The people who argue dogmatically against any use of gotos are missing Dijkstra's main point. While the title of the paper is about gotos, the body is mostly concerned with discussing how programs can be structured so that it is feasible to reason about their correctness.

      When this paper was written, gotos facilitated the rampant production of confused and confusing spaghetti code, and many programmers believed gotos were required to write certain types of program. At that time, banning gotos seemed like the only thing that could fix this. Since then, we have learned a couple of things:

      1) Good programmers will write well-structured code even when they have the option to use gotos (and even if they actually do.)

      2) Confused programmers will write confused code even while adhering to structured syntax rules.
       

    233. Re:why? by Anonymous Coward · · Score: 0

      I don't think I would so much call GOTO "harmful", so much as "completely unnecessary in any modern language".

      How interesting, since exception handling and automatic object cleanup is basically a more advanced (and automated) form of GOTO.

    234. Re:why? by Anonymous Coward · · Score: 0

      The success flag as you show it does not require nesting.

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

      I use this "run the gauntlet" pattern often, (though admittedly, nesting would remove the redundant
      boolean testing during fall-through of a failed condition).

    235. Re:why? by TzadikV · · Score: 1

      setjmp and logjmp were available in most compilers long before they became "standard"

    236. Re:why? by Anonymous Coward · · Score: 0

      , the Java designers overreacted and prohibited it

      A common misconception.

      LABEL_NAME : for (Item i : list ) {
      if(i == null)
          continue LABEL_NAME;
      else
          break LABEL_NAME;
      }

      It's a goto but with enhancements to make it better. Switch statements are gotos as well.

      Labeling of nested loops for continue and break will help you to better write what some people call "self-documenting code".

    237. Re:why? by HappyPsycho · · Score: 1

      This sounds exactly like an exception.

    238. Re: why? by Anonymous Coward · · Score: 0
    239. Re:why? by KlomDark · · Score: 1

      But why you all mad about it?

    240. Re: why? by theburp · · Score: 1

      I know what you're getting at but you wouldn't want to do that here. If you did, and you failed, how would you know at which point you failed? This is, of course, assuming you cared about this for resource freeing or something.

    241. Re: why? by Anonymous Coward · · Score: 0

      You still have the opportunity to provide a clear and distinct error message for each failing checkpoint in the gauntlet. Which you wouldn't get with "if ( doSomethingThatMightFail() && doSomethingElseThatMightFail() && doMoreFailingStuff() && yepMoreFailingStuff() ) { ; } else { cleanupWork(); }". It's a brief, contrived example, not necessarily indicative of real-world usage. It should imply nothing more than I don't prefer to chain function invokations via "Boolean and".

      My point is that even in the case offered in the GP post, goto is not necessary. And preprocessor macros are even more evil than goto...

    242. Re: why? by Anonymous Coward · · Score: 0

      i guess the linux kernel has serious design issues, because it is sprinkled thru out with gotos. :/

      you are scared to use gotos so you find every possible way to avoid them. meanwhile the code you wrote to replace the gotos does exactly what a goto would do anyway.

      this advice was given over 20+ years ago. languages are a lot smarter and cater more to writing clean code these days, and yet goto is still a construct in almost all languages. go figure.

    243. Re: why? by Anonymous Coward · · Score: 0

      hear hear

    244. Re: why? by Anonymous Coward · · Score: 0

      just because your afraid of using gotos, your code is less readable.
       

    245. Re:why? by Anonymous Coward · · Score: 0

      When I'm in a need-to-cleanup scenario, I've always used early returns instead of gotos. Have a function do the allocations, pass it off to another function, that function hits a condition where it needs to quit early, returns, the function that allocated the resources cleans them up.

      I would use the goto if I were in a situation where I really couldn't afford the extra function call overhead, but I've never been in a situation that resource constrained.

    246. Re:why? by Dutch+Gun · · Score: 1

      Part of the problem is, the examples are really too small to call either way.

      Interestingly enough, I recently took a peek at one of Linus' latest patches (regarding the OS' ability to patch without rebooting), and examined the use of goto in that code. This is "real world" code, and saw three uses of goto, and each one seemed perfectly reasonable and easy-to-follow.

      --
      Irony: Agile development has too much intertia to be abandoned now.
    247. Re:why? by Anonymous Coward · · Score: 0

      That's a horrible example. You are BYPASSING cleanup with that goto.

    248. Re: why? by Anonymous Coward · · Score: 0

      Actually his example is not as realistic as it can get. Usually, when there's an error the cleanup depends on where the error occurred. Often it requires unwinding the exact same number of levels inside the onion you've descended. In that case, a cleanup section with several labels that can be goto'd is far cleaner than the alternatives. It's done frequently in the Linux kernel for good reason.

      Your idea doesn't help in that case: If you use && to chain together several function calls, you lose track of where the error occurred.

    249. Re:why? by Anonymous Coward · · Score: 0

      Really? You've not written a single C program during your "thousands of projects" whose error cleanup would be better handled with gotos?

      Usually, when there's an error the cleanup depends on where the error occurred. Often it requires unwinding the exact same number of levels inside the onion you've descended. In that case, a cleanup section with several labels that can be goto'd is far cleaner than the alternatives AND removes the need to duplicate the cleanup code in every early-return that you propose. It's much more maintainable and readable, not to mention a small reduction in binary size. Gotos are done frequently in the Linux kernel for good reason.

    250. Re:why? by shutdown+-p+now · · Score: 1

      Also, depending on the language, using goto to break out of nested loops can lead to stack overflow.

      Can you give an example of such a language?

    251. Re:why? by strikethree · · Score: 1

      Only pendants are convinced the issue is black and white.

      I am really sorry but I just can't help myself. The mis-spelling of the word pedants is just too humorous to pass up. ;)

      --
      "Someone needs to talk to the tree of liberty about its ghoulish drinking problem." by ohnocitizen
    252. Re:why? by dgatwood · · Score: 1

      I was talking about:

      f(result==OhShit) {foo.unwind(); foo.cleanup(); foo.bar(); foo.close(); foo.dispose(); foo=null;}

      Which is okay as long as it happens only once, but if you end up with several returns, and you need to add foo.releaseNetworkConnections() to all of them, odds are good that you'll miss one, and now you have a leak (at least).

      --

      Check out my sci-fi/humor trilogy at PatriotsBooks.

    253. Re:why? by fahrbot-bot · · Score: 1

      Only pendants are convinced the issue is black and white.

      I am really sorry but I just can't help myself. The mis-spelling of the word pedants is just too humorous to pass up. ;)

      Ya, you're not the first to comment on my fat-fingers - though that you (both) felt compelled to do so might say more about you two than me. :-)

      --
      It must have been something you assimilated. . . .
    254. Re:why? by mike4ty4 · · Score: 1

      So when is it OK or not OK to use a "goto" to handle errors, and what are the alternatives? When you have multiple steps which can fail and you have buffers allocated, for example? As this is where it would seem most tempting to use a goto. But as you say, rules aren't meant to just be "obeyed", so if the goto lets you have a common return statement and save from duplicating the deallocation code, sounds like a good idea to me.

    255. Re:why? by Pseudonym · · Score: 1

      That's true of C, but not of C++. In C++, it's even more crucial to maintain nested scopes because of destructors.

      The good news is that destructors make goto-style error handling even less necessary.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    256. Re: why? by Pseudonym · · Score: 1

      The snag with exceptions is that with many embedded systems they may take too much overhead.

      This is 100% correct, but the weirdest part is that exceptions were invented for use in hard real-time embedded systems, specifically the operational flight program for the A-7E aircraft. The team (and David Parnas in particular) realised that any piece of hardware could fail at any time, and the plane would have to keep flying, however it was undesirably to clutter the "straight line" logic with all of this error condition stuff.

      --
      sub f{($f)=@_;print"$f(q{$f});";}f(q{sub f{($f)=@_;print"$f(q{$f});";}f});
    257. Re:why? by Anonymous Coward · · Score: 0

      Isn't the break keyword sort of a carefully controlled goto, particularly when break is allowed with labels for multi-level breaks?

      Goto is crude when used as a crutch, just as a streetlight can be no more than a prop to keep a drunk programmer on his feet. There are those of us, however, who use goto, sparingly, for illumination.

      Yes. There are illuminati. By our genius use of goto shall you know us.

    258. Re: why? by daviskw · · Score: 1

      I've never worked at a job where I would not have been fired for that lazy crap example you just coded.

      Logically, if you place an else or if you return from the function early you avoid having the need for the goto. Its lazy and it goes against every coding standard I've ever seen and unless you are Larry Wall (Perl designer and coder and goto apologist) you don't get to use them.

      --
      Beware the wood elf!!!
    259. Re:why? by Anonymous Coward · · Score: 0

      And that only works if your cleanup code can deal with all things that might fail as if they did in fact fail.

      Frequently not the case Think freeing a pointer twice or freeing a pointer not yet assigned. And then your code won't work.

    260. Re:why? by toddestan · · Score: 1

      That's pretty much it. Since C doesn't have exception handling I use goto to accomplish something similar. That's about the only reason I ever use goto so generally I don't find it harmful when it comes to code I've created because if I see it, I know what it's doing. Of course, if it's something that someone else wrote, it could be doing just about anything, but it's not like you can abuse other language constructs.

    261. Re:why? by pla · · Score: 1

      Yes, really.

      I stopped using GOTO when I moved beyond GW-Basic some 25 years ago. And I've used plain ol' C for the majority of the code I've written in my life. And yes, FWIW, I've written firmware - Low-level coding, unless done in assembly, doesn't give you a pass on flagrantly breaking the built-in flow control devices of a language.

      If you need to resort to a GOTO, you did something wrong before you ever typed your first "#include ...". Simple as that. Yes, you can defend various uses of it, and no, most of them probably don't merit invoking Dijkstra's Wrath. Most of them don't count as outright harmful, just unneccessary. But for every use case you can come up with, I can give you a non-GOTO way of handling every... single... one. As I mentioned, I've re-written plenty of code to remove the GOTOs from it. You just don't need them, period.

    262. Re: why? by Anonymous Coward · · Score: 0

      I solved the problem by making an instruction set without any jumps.

    263. Re:why? by strikethree · · Score: 1

      Ya, you're not the first to comment on my fat-fingers - though that you (both) felt compelled to do so might say more about you two than me. :-)

      In this particular case, it is not about you, it is about the humour. It could have been anyone... even me. It is not the fact that a mistake was made that is important, mistakes are common in casual conversation like this. It is that the mistake was made in relation to the meaning of the word that the mistake was made upon (is that even coherent?!). :)

      --
      "Someone needs to talk to the tree of liberty about its ghoulish drinking problem." by ohnocitizen
    264. Re:why? by Jane+Q.+Public · · Score: 1

      But perhaps you mean a goto that skips over function boarders? Not sure if you can do that in C and C++, if you can do that ofc. the stack is in your hands :) and you are at mercy of its limits.

      Not necessarily. I was mainly referring to old languages that didn't properly clean up after themselves. Certain old versions of BASIC for example. They weren't even procedural, so there were no "functions", it was all inline code.

      And it was certainly possible to do. Just create a loop that executed another loop enough times, and GOTO out of the second loop in such a way that the first loop kept running.

      Loop setup would push the current context on the stack and set up the loop. The GOTO would ensure that the cleanup code in the second loop was never reached. Push push push and no pop. Stack overflow.

    265. Re:why? by angel'o'sphere · · Score: 1

      Sorry, loops in basic don't work that way. There is no stack usage involved at all.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    266. Re:why? by Anonymous Coward · · Score: 0

      Alternatively...

      static int
      do_some_work (context_t context,
                                  int x,
                                  error_t **error)
      {
              int rv = 0;
              database_t *db;
              data_t v;

              db = get_db (context, error);

              do some work ...

              v = compute_v (context, db, error);
              if (v){
                      more work ...
              }
              return rv;
      }

    267. Re:why? by Anonymous Coward · · Score: 0

      Alternatively

      if (! doSomethingElseThatMightFail()) {return;}
      if (! doSomethingElseThatMightFail()) {return;}
      if (! doMoreFailingStuff()) {return;}
      if (! yepMoreFailingStuff()) {return;}
                   

    268. Re:why? by Jane+Q.+Public · · Score: 1

      Do you even read the comments you reply to?

      I referred to SOME, OLD versions of BASIC. And yes, loops did use the stack. Not heavily, but they pushed the current context onto the stack on entry.

      I've actually done this, man. (Unintentionally, but I did it.) And yes, the result was a stack overflow.

      If you want to show me a disassembly of the particular languages I was talking about, by all means do so. But I doubt you can, since I didn't even mention what they were.

      I call bullshit on your calling of bullshit. We could do this forever.

    269. Re:why? by angel'o'sphere · · Score: 1

      Sorry, that does not make any sense.
      But if you believe it was like that, who am I to teach you different :)

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    270. Re:why? by UnderCoverPenguin · · Score: 1

      Were you intending to reply to ShanghaiBill's post?

      If me, I was only curious how he would write the subfunctions into which he deferred the lower level parts of the error handling.

      --
      Don't try to out wierd me, three-eyes. I get stranger things than you, free with my breakfast cereal. --Zaphod Beeblebr
    271. Re:why? by Anonymous Coward · · Score: 0

      Coming from an IBM assembler shop, I have always ignored the goto scare mongers. Assembler is completely goto, so I continued to use it in C++, Pascal, and every other language that allowed it. I first conformed to this nogoto nonsense, but when I caught one of my programs having to back-flip out of a routine several times once, I went back to gotos.

    272. Re:why? by Jane+Q.+Public · · Score: 1

      I'd prove it to you but I don't even have a reasonable way to install and run those languages again.

      I have no idea why you say "it doesn't make sense". There's nothing strange about it at all. At least, if you were around Back In The Day it wouldn't seem strange to you. Of course, you had fewer registers to play around then with too. But the basic idea is very simple:

      Code a loop. When the code reached the loop, the interpreter would cause the instruction pointer and often some data to be pushed on the stack. It might be only a couple of bytes; doesn't matter.

      Now, INSIDE the loop, you could use a "break" to cleanly exit. But a hard GOTO would not; those few bytes did not come back off the stack. Not from the loop itself, you understand, but from a push that happened just before it.

      Do that enough times, you get stack overflow.

      I'd be the first to admit I don't know of any current language that is that "dumb". But there certainly used to be. I also agree that it would be dumb to do that intentionally. But I was in the business of coding very complex programs in a very dumb language. Occasionally accidents like that did happen.

    273. Re:why? by Anonymous Coward · · Score: 0

      I'm sure the academic could probably convince you to rewrite the code to remove the goto statements.

      The problem is convincing the client to pay for the extra time needed to refactor the code. In the real world, the client (who pays for the code) only cares about results, not how academically correct the code is (or isn't as it may be).

    274. Re: why? by vilanye · · Score: 1

      What if you have to clean up memory on the error condition?

    275. Re:why? by vilanye · · Score: 1

      You just put acquiring resources in your critical path.

      smh

    276. Re:why? by vilanye · · Score: 1

      So you don't allow break or continue? Because there is no real difference in C between them and GOTO.

    277. Re:why? by vilanye · · Score: 1

      "Don't prematurely optimize" is another one of those proverbs that people worship without thinking about it.

      Yup

      People have taken that to mean that it is okay it write poor code because the compiler will save you and if it doesn't then you can do it the right way.

      Most of the time I know the optimal way to write it so I do. Waiting is pure stupidity.

      If I am not sure, I come up with the best that I can, profile it and if it isn't efficient enough I tweak it.

    278. Re:why? by vilanye · · Score: 1

      And GOTO is function local.

      There is zero difference between those breaks and GOTO except that using GOTO won't kill your cache.

    279. Re: why? by ilsaloving · · Score: 1

      You've missed my point completely. It's not about how difficult it is to implement. It's about knowing when to implement it.

      And I've seen enough hideous code to say that way too many programmers are not skilled enough to realize that they don't know how to make that judgement call, so it is infinitely simpler to simply advise them to not use certain constructs.

    280. Re:why? by squiggleslash · · Score: 1

      Nah, he's mostly right although stack underflow was more of a problem than stack overflow. FOR...NEXT frequently manipulated a stack in many older 1980s BASICs.

      At that time, each command was executed independently of every other command. The program wasn't pre-parsed, beyond tokenization and making a note of where the line numbers were. When you executed a "FOR" statement, the location of the FOR was put on the stack, so that when you executed NEXT, it could return to that FOR statement if the loop wasn't finished.

      Which means if you had a program like this:

      5 ' Contrived example to draw a right angled triangle twice as high as it is long. 10 FOR I=1 TO 10 20 X=0 30 IF X=2 THEN GOTO 90 40 X=X+1 50 FOR J=1 TO 10 60 IF I=J THEN PRINT : GOTO 30 70 PRINT "."; 80 NEXT 90 NEXT

      ...then you'd end up with a holy mess, the program wouldn't work as expected (which in this example is fine, it's contrived, I have no idea why you'd write code this bad), largely because the NEXT statement at line 90 would be used to repeat the J loop when X=2.

      Some BASICs let you name the loop variable in the NEXT statement. Some even required it. But not all. And those that didn't lead programmers to end up banging their heads over more subtle cases of the above happening.

      --
      You are not alone. This is not normal. None of this is normal.
    281. Re: why? by TechyImmigrant · · Score: 1

      And I am disagreeing with you.

      If someone is using goto inappropriately, more often than not, because they're failing to adopt the house style, then the 'new learning' they need does not require years of experience to acquire. It's a five minute conversation, because it's really not that complicated.

      Some things in software are complicated. This is not one of them.

      --
      I should use this sig to advertise my book ISBN-13 : 978-1501515132.
    282. Re:why? by angel'o'sphere · · Score: 1

      I believe I slowly remember that you are right.

      The position of the FOR token, or the concrete start of the loop afterwards was really on the stack.

      I likely never had a program that did goto out of a loop though.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    283. Re:why? by Hognoxious · · Score: 1

      I've used that trick ... in languages that don't have goto.

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
    284. Re: why? by Hognoxious · · Score: 1

      break can't break out of two loops in many popular languages.

      You just have each loop be conditional on a breakout flag. Of course you'd either have to have separate flags for each nesting level and set them appropriately before pulling the handle, or make the while (or is it until?) clause check all higher (or is it lower?) level flags.

      In any case those are trivial implementation details and I'm sure it would be exponentially better and cause ShanghaiBill to literally shit his pants, retire on the spot and hire you as his replacement.

      --
      Confucius say, "Find worm in apple - bad. Find half a worm - worse."
  3. XKCD by rhazz · · Score: 4, Funny

    Obligatory: http://xkcd.com/292/

    1. Re:XKCD by Radical+Moderate · · Score: 1

      Heh, I clicked your link, then wasted some time there, which led me to this: http://xkcd.com/301/

      --
      Never let a lack of data get in the way of a good rant.
    2. Re:XKCD by rhazz · · Score: 1

      +1 sad but true.

  4. 99% of cases: by Culture20 · · Score: 0

    FART: printf("FART\n"); goto FART;

    1. Re:99% of cases: by Anonymous Coward · · Score: 0

      soup vlad

    2. Re:99% of cases: by Culture20 · · Score: 1

      That doesn't use goto. The researchers were interested in uses of goto.

  5. 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?

    1. Re:How much unsafe use has Dijkstra prevented? by Anonymous Coward · · Score: 5, Interesting

      As someone who saw the programming practices of the 1960s and early 1970s, I can assure you that Dijkstra's warning was needed.
      It caused a massive change in practices among software professionals, within a few years GOTO had almost disappeared from most new code.
      I remember seeing code from a "sales engineer" in 1975 that was so full of buggy gotos that we refused to even attempt to debug it.
      He learned.

    2. Re:How much unsafe use has Dijkstra prevented? by MightyYar · · Score: 1

      Yes, because people would have run into those problems and someone else would have made the same warnings.

      He probably saved someone a lot of grief way back when, though.

      --
      W..w..W - Willy Waterloo washes Warren Wiggins who is washing Waldo Woo.
    3. Re:How much unsafe use has Dijkstra prevented? by david_thornley · · Score: 1

      For quite a few years afterwards, I was hearing the phrase "gotoless programming". I'm not sure that was much of an improvement.

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
  6. can we have alter now? by Anonymous Coward · · Score: 0

    If we're now allowed to have GOTO, can we have ALTER as well?

    PLEASE!

  7. 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.
    1. Re:What's the term for a prophylactic prediction? by Anonymous Coward · · Score: 0

      This was exactly what I planned to write, but you took the words right out of my brain. I'm going to post this AC so I can mod you up.

    2. Re:What's the term for a prophylactic prediction? by gnasher719 · · Score: 0

      Actually, most software developers haven't heard of Dijkstra but just figured out that using goto is rarely the best thing to do, or even as good as other solutions.

      Dijkstra wrote this at a time where FORTRAN didn't even have an if/else/endif statement. if (x > 0) y += 1; else y -= 1; required two labels and two gotos! No wonder code was hard to read because of goto's. But today nobody would use a goto in this situation, not because of Dijkstra, but because it is an obvious bad idea.

    3. Re:What's the term for a prophylactic prediction? by ewibble · · Score: 1

      I agree, but i can only think of one instance that gotos are appropriate and that is cleanup. I think this is basically because C does not have any nice way to handle cleanup, a finally block would get rid of most valid uses of goto.

    4. Re:What's the term for a prophylactic prediction? by mariox19 · · Score: 1

      The term you're looking for is good judgment

      --

      quiquid id est, timeo puellas et oscula dantes.

    5. Re:What's the term for a prophylactic prediction? by ultranova · · Score: 1

      I agree, but i can only think of one instance that gotos are appropriate and that is cleanup. I think this is basically because C does not have any nice way to handle cleanup, a finally block would get rid of most valid uses of goto.

      Problem is, a finally block effectively changes the meaning of code within it by tagging any return statements with extra code. A line being changed by another line far away seems far more inelegant and prone to confusion than goto.

      --

      Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

    6. Re:What's the term for a prophylactic prediction? by Pinky's+Brain · · Score: 1

      If you have a formal education you have heard of his name for A*.

      If you don't you will at the very least have heard the sentence Goto Considered Harmful ... and I think we can all agree it's a snappy turn of phrase, hard to forget and by now iconic. Unless you lock someone up in a cave with The C Programming Language before they learned any programming I think they'll have heard of it by the time they are proficient with C.

    7. Re:What's the term for a prophylactic prediction? by dbc · · Score: 2

      Indeed. And if one is old enough to have read/maintained any FORTRAN code dating from Dijkstra's era, you can understand why he wrote this paper. A lesser being would have gone off on an apoplectic rant. In fact, I may be one of those lesser beings, myself.

    8. Re:What's the term for a prophylactic prediction? by BlackPignouf · · Score: 1

      It reminds me of a joke. It was something like :
      * What do you do for a living?
      * I protect the population : I'm a velociraptor hunter
      * But, there's no velociraptor!
      * You're welcome.

    9. Re:What's the term for a prophylactic prediction? by tepples · · Score: 1

      Either way, except in narrow cases, such proofs are essentially impossible.

      "Managed" environments, such as JVM, CLR, and JavaScript, have made it at least possible to prove that a program is type-safe.

    10. Re:What's the term for a prophylactic prediction? by frank_adrian314159 · · Score: 2

      to prove that a program is type-safe.

      Which usually is, as it has almost always been, the least of one's worries.

      --
      That is all.
    11. Re:What's the term for a prophylactic prediction? by SuricouRaven · · Score: 1

      Some of us like unsafe languages. They let you carry out ridiculous abuses for performance reasons. Like treating pixels in a bitmap as an array 64-bit ints so you can carry out boolean operations quickly, or as an array of chars for arithmatic operations - whichever works best at the time. This sort of low-level, unsafe stuff is why C and similar languages remain the fastest around.

    12. Re:What's the term for a prophylactic prediction? by david_thornley · · Score: 1

      Finally blocks suck, but many languages have to live with them. Lumping all the cleanup code together is poor cohesion, and it's very tightly coupled with the processing code. If you change code in the main processing, you have to change the cleanup code, and that's additional room for making mistakes. Scope-based destructors handle cleanup far better (of course, you pay for that in other ways).

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    13. Re:What's the term for a prophylactic prediction? by Brett+Buck · · Score: 1

      Whether he was right or wrong, people have taken his statements, as with most religious zealots, to the ultimate ridiculous end.

            I heard the capper in about 1988 or so, when one of our customers asked, during a code review, if an unconditional branch in assembly code wasn't just like a GOTO, which was prohibited.

       

    14. Re:What's the term for a prophylactic prediction? by tepples · · Score: 1

      Some of us like unsafe languages. They let you carry out ridiculous abuses for performance reasons. Like treating pixels in a bitmap as an array 64-bit ints so you can carry out boolean operations quickly

      In theory, an array type that supports long, byte, and bit access to the same data could be made type-safe. One complication is that different machines have different byte orders.

    15. Re:What's the term for a prophylactic prediction? by angel'o'sphere · · Score: 1

      This sort of low-level, unsafe stuff is why C and similar languages remain the fastest around. For that stuff

      FTFY.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    16. Re:What's the term for a prophylactic prediction? by Megol · · Score: 1

      That isn't an advantage over safe languages - there are examples of safe type systems that allow such operations.

    17. Re:What's the term for a prophylactic prediction? by Megol · · Score: 1

      Depends on how comprehensive the type system is. For some examples look at Microsoft Singuarity/Sing# and the BitC language. Verified usage protocols are a very powerful feature.

    18. Re:What's the term for a prophylactic prediction? by Cederic · · Score: 1

      Actually, most software developers haven't heard of Dijkstra but just figured out that using goto is rarely the best thing to do, or even as good as other solutions.

      Worrying if most programmers haven't heard of Dijkstra, but they've also learned how to program - and that's very very difficult without learning from someone that (directly or otherwise) has been influenced by that single Dijkstra paper.

      "How do I do X" - well, here's the best practice from the last four decades, none of which involves the use of 'goto' because four decades ago everybody had read the paper and realised the point it was making.

    19. Re:What's the term for a prophylactic prediction? by shutdown+-p+now · · Score: 1

      In theory, an array type that supports long, byte, and bit access to the same data could be made type-safe.

      CLR has this in practice:

      https://msdn.microsoft.com/en-...
      https://msdn.microsoft.com/en-...

      Also [StructLayout(LayoutKind.Explicit)] is somewhat similar (and is considered verifiably safe so long as you only overlap blittable types, and don't use types with architecture-dependent size like IntPtr).

  8. goto fail by Anonymous Coward · · Score: 5, Informative

    https://www.imperialviolet.org/2014/02/22/applebug.html

    1. Re:goto fail by geantvert · · Score: 1

      The same bug would have occured if goto had been replaced by a break, a return or a throw.
      The problem in that code was not the GOTO but the indentation.

    2. Re:goto fail by angel'o'sphere · · Score: 1

      The wuestion what the real bug is or problem is is subjective.
      For me the extra goto is the bug, as it was obvious regardless of indentation.
      But some people read different, hence some coding guidelines require braces also for one liners.
      I never got the stupid 'wrong indentation' arguments. If you have trouble with wrong indentations, because your eyes, your mind or what ever is boggled by it, then run a code formatter after checking out of the source controll adjusted to your likening.

      The language was C, remember? Identation does not matter at all. The whole function could have been written on one line.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    3. Re:goto fail by Anonymous Coward · · Score: 0

      And that, boys and girls, is why you always use the block braces on IFs and FORs.

      Seriously, it's 5 fucking buttons ('space', '{', 'enter', code body, 'enter', '}'), just do it.

    4. Re:goto fail by Anonymous Coward · · Score: 0

      Yes, this is my beef with this research. It's almost exactly a year after the publication of goto fail and the GNU TLS bug that was also related to this "clean" goto idiom (see https://www.gitorious.org/gnutls/gnutls/commit/6aa26f78150ccbdf0aec1878a41c17c41d358a3b).

      It seems strange to claim that these things don't happen. And even if they happen rarely, we have seen that they can happen in very high-profile software and have a disastrous impact. In short, the probability of failure does not seem to be the right measure here, it should be something like the expected value of economic damage. But that's impossible to quantify, of course.

      (Also, the sample size of 384 seems very small, even if they can formally claim statistical significance.)

  9. Well, yeah by Anonymous Coward · · Score: 4, Informative

    Because we all got the warning, and thus did not write horrible goto-festooned spaghetti code and only use goto when appropriate. This means Dijkstra's letter was a success. Also, it was Niklaus Wirth who decided to use the "considered harmful" verbiage, not Dijkstra.

    1. Re:Well, yeah by HBI · · Score: 2

      Agreed. One must think back to the BASIC, PL/I or Fortran-dominated 70s to understand why Djikstra might have been worried. The problem was solved in practice.

      --
      HBI's Law: Frequency of calling others Nazis is directly correlated with the likelihood of the accuser being Communist.
    2. Re:Well, yeah by narcc · · Score: 2

      Now, we write horrible, impossible-to-follow, spaghetti code without goto!

      Remember kids, 'spaghetti code' refers to code with complex *control flow*. That is, if you trace it with a pencil, you end up with a document that looks like a plate of spaghetti. We're, arguably, worse-off now than we were before goto became taboo.

      We learned the wrong lesson.

      In smalltalk, everything happens somewhere else. --Adele Goldberg

    3. Re:Well, yeah by rujasu · · Score: 1

      If you think modern code is horrible spaghetti (I disagree, for the record), bear in mind that it would be considerably worse with indiscriminate use of goto.

      Sure, code has complex code flow. When code is designed to solve complex problems, it's going to be complex. Complexity is okay. The key is being able to make complex code clear, readable, and less error-prone. Goto is less clear and readable because it's not obvious what a goto statement is meant to do. When you see a while loop, or a break statement, or a function call, you can get an idea of what it's doing just by the nature of what statement is being used. Goto can be used to cover any of those cases, so it's more difficult to follow. Because of this, it's also easier to make a difficult-to-debug mistake!

      99% of the time, when you could use a goto statement in code, there is another, better way of doing the same thing. An expert coder will be able to effectively use it in a way that limits the risk, but for a novice or intermediate coder, or even many experienced ones, it is much easier to muck everything up using goto vs. using other control flow tools.

    4. Re:Well, yeah by narcc · · Score: 1

      Where's the evidence? What you're repeating is received wisdom -- which lacks any sort of empirical foundation.

      Sure, I've seen messes made of goto. I've also seen messes made of nested if's that would be cleaner and easier to read had the developer made proper use of goto.

      Goto can be used to cover any of those cases, so it's more difficult to follow.

      Should we then claim that conditional iteration is harmful and ban its use?

      "What?" You ask. Allow me to explain. There are five essentials of control flow: Direct sequencing, conditional and unconditional branching (if, goto), and bounded and conditional iteration (for, while).

      Bounded iteration and conditional branching are can be trivially simulated using conditional iteration. You never need goto, as its use can always be avoided with enough wrangling, so it can replace in practice, if not directly, the unconditional branch as well. When you see a while, then, it could be being used for any control-flow operation. What a horrible thing! Imagine the mess that developers are sure to make tossing "while's" all over the place!

      It would be stupid, of course, to ban "while" on those grounds just as its stupid to ban goto on those grounds. Conditional iteration is very helpful, when used as intended. Goto, likewise, can make your code easier to read. After all, sometime avoiding goto (or its doppelgangers, break and the early return) can lead to some messy code.

      when you could use a goto statement in code, there is another, better way of doing the same thing

      The best argument you make against goto is that it's unnecessary. Of course, with just the conditional and unconditional branch, we can eliminate every other control structure. Should we ditch those instead? We could take it a step further, as you know, and eliminate everything but the while loop!

      To be fair, you did say "99% of the time" and use the nebulous qualifier "better". Still, why hurt yourself, and your code, in that remaining 1%? Because someone once told you it was bad?

    5. Re:Well, yeah by ilsaloving · · Score: 1

      Just peruse http://www.thedailywtf.com/ if you need emperical evidence.

      That is a neverending wealth of evidence of how badly people code.

      But your argument is silly. Of course banning conditional loops is dumb. You're right A determined programmer can make hash out of any programming language. The question becomes a matter of how easy it is for Dunning-Kruger code monkeys to mutilate their code while thinking they are doing things properly.

      It's about raising the bar and forcing people to think in a more structured way.

      "Banning" goto is like "Banning" jaywalking. Because enough people screw it up badly enough that it is simpler to just warn against it in general.

    6. Re:Well, yeah by narcc · · Score: 1

      That is a neverending wealth of evidence of how badly people code.

      Yes, people write bad code. It's not a revelation. That has nothing to do with my request, however.

      But your argument is silly. Of course banning conditional loops is dumb.

      Of course it's silly, that was the point! That someone can misuse a control structure does not mean there is some fundamental problem with it. Everyone agrees with that until you mention goto, then they cry "blaspheme!".

      Equally silly, of course, are the other arguments against goto. Rather than empty rhetoric, I'd like to see some actual evidence before I join the church of goto sucks. Is that too much to ask?

      Right now, I'm staring at an empirical study that contradicts the received wisdom from the holy prophet Dijkstra.

      "Banning" goto is like "Banning" jaywalking. Because enough people screw it up badly enough that it is simpler to just warn against it in general.

      I'll ask you these then: When was the last time you saw someone use a goto in such a way that it harmed the programs readability, efficiency, or otherwise? When was the last time you saw someone structure their code to avoid a goto that make the program less readable, efficient, or otherwise.

      I've seen bad code that uses goto, though I can't attribute those messes to the use of goto -- as you've pointed out, developers can make a mess with anything. I have, however, seen code that was messy because the developer wanted to avoid using a goto or where a goto would have made the code smaller and easier to read and reason about.

      Still, that's just our combined experience. I'll assume that we're at an impasse as your experience differs dramatically from my own. The only way for us to resolve this is if we were to provide some actual evidence. To start, I'll offer you the study linked in the summary.

    7. Re:Well, yeah by rujasu · · Score: 1

      The point is that people do not generally use goto in these harmful ways because they've been warned not to. That's what skews the study in the summary. You're going to have a hard time finding that empirical evidence of how goto can lead to bad code, because one of the first things coders are taught in today's programming courses is, "Do not use goto." Meaning that the inexperienced coders who would be having these problems are avoiding the problem by not using goto. Those who are using goto are those who know the risks and how to mitigate them.

      So, in the absence of conclusive data either way, I can only argue from my experience. I'm a programmer who has used both goto and more tightly-controlled flow control, and in my experience goto is not a good option for the vast majority of cases (particularly for inexperienced coders).

    8. Re:Well, yeah by angel'o'sphere · · Score: 1

      The 'while programming language' which only has functions/procedures and while as constructs actually exists as a teaching convept in (computational) theoretical computer sciense.

      As I was a quite capable Pascal programmer already at the time it was used in university, doing the homeworks and assignments was just an finger excersise to me at that time.

      But it was funny

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    9. Re:Well, yeah by narcc · · Score: 1

      The solution, then, is to stop teaching students such silly things until we can manage solid evidence either way.

      With nothing conclusive, let's just let the silly meme die. Further propagating it is harmful, regardless of the future outcome.

    10. Re:Well, yeah by rujasu · · Score: 1

      Stop teaching students to avoid goto so that it takes hold again, leading to bad code all over the place, so that we can empirically prove that it's a bad idea? How about we just don't do that and avoid the problem to begin with.

      Unrestrained use of goto was demonstrated to be a bad idea decades ago, that's why Dijkstra recommended against it in 1968.

    11. Re:Well, yeah by narcc · · Score: 1

      leading to bad code all over the place

      On what basis did you come to that conclusion?

      Unrestrained use of goto was demonstrated to be a bad idea decades ago

      That's the point -- it was NOT shown "to be a bad idea". Further, this study suggests that Dijkstra's fears were not realized.

      If you want to base your beliefs on the words of a holy prophet, and not on proper evidence, that's up to you. Just don't expect anyone else to go along with it.

    12. Re:Well, yeah by shutdown+-p+now · · Score: 1

      I think that you're attacking the wrong thing. Control flow in modern programs is just as complicated, yes. Ultimately, there's no way around it - a complex system with many states requires a complex control flow. What we're better at is organizing the code structure (which is different from how execution flows through it!) in such a way that it can be digested one bit at a time, rather than having to grasp the entire thing at once that was more common back in IF..GOTO days.

    13. Re:Well, yeah by rujasu · · Score: 1

      Has nothing to do with "holy prophets" or anything like that. I've done programming with and without goto, and goto is (usually) bad. I knew this before I ever heard of Dijkstra.

      The study says that goto has not been a problem BECAUSE it is not being used inappropriately. Inappropriate use is exactly what Dijkstra cautioned against. So the study isn't saying anything other than that people did exactly what Dijkstra suggested they should do.

  10. 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.

    1. Re:all languages can be abused by narcc · · Score: 1

      If you look at the code most C compilers come up with they are not afraid of a goto

      As if they had a choice!

    2. Re:all languages can be abused by rujasu · · Score: 1

      Not sure what you're getting at with compilers. Once you translate a C program to assembler/machine code, most of your loops, switches, breaks, etc. all become effectively the same as goto. The problem with goto has nothing to do with the compiler, it has to do with the human being trying to read, write, and debug the code before it goes through the compiler, and with catching errors at compile-time with sane control flow, whereas with goto it will make it through the compiler and become a runtime error.

      You complain about the giant if/for nests, but those huge nests will almost always become worse if you start throwing gotos in there.

      Yes, goto is a tool like anything else. But it is not a tool for the common case or the common coder. Most of the time, if you're asking yourself, "should I use goto here or something else?" the answer is the something else.

  11. To be expected by PhrostyMcByte · · Score: 2

    This makes sense for a couple reasons.

    First, abusing goto really serves noone. It doesn't make code quicker to write. It certainly doesn't make it easier to understand. There is no benefit to it.

    Second, I'd argue that very few people want to write new code in C these days. Those who do have specific reasons for it and are probably a bit more experienced or passionate and thus aren't the kinds of people who'd readily abuse things. The ones who would are going to be mostly attracted to easier high-level languages that don't allow the abuse in the first place.

    1. Re:To be expected by The+New+Guy+2.0 · · Score: 1

      Goto these days is a stenography tool... it's designed to make the code harder to read.

    2. Re:To be expected by DamonHD · · Score: 1

      Lots of 'Internet of Things' code will be written in C (with some ASM and C++) as the 'things' tend to be resource constrained. That's a big market coming up.

      I'm enjoying using C again on devices with similar performance to those I was using 30 years ago (now: ATMega328P running with 1MHz CPU, ie 1 MIPS; then Z80A with 4MHz clock making for ~1MIPS) but with lots better development tools this time, and several GHz of laptop to run them on.

      https://sourceforge.net/p/open...

      When not writing C (and developing hardware) I knock out (parts of) huge mission-critical Java systems for banks.

      Each is good: each for its niche.

      Rgds

      Damon

      --
      http://m.earth.org.uk/
    3. Re:To be expected by Anonymous Coward · · Score: 0

      "Steganography", not "stenography".

    4. Re:To be expected by itzly · · Score: 1

      Lots of Internet of Things stuff runs on ARM Cortex M3/M4 on > 100 MHz CPUs. Plenty of resources for lazy development.

    5. Re:To be expected by Anonymous Coward · · Score: 0

      I work with embedded devices. These things are limited (small battery, long life, low cost etc). Every clock tick costs power.
      A good programmer writes nicely structured code which is efficient as well.

      One of many hard-won words of wisdom: the common (or "fast") path through the code should have no taken branches. All non-most-common cases should bail out and be handled by the unusual (or "slow") code. You have to write your code so the compiler has a fair chance. Any funnily enough, the cleanest way to write such code is by using goto to bail to the slow path. The fast path becomes very clean, as does the slow path. Check out e.g. real networking stacks (Linux is good in this respect), but most are the same.

    6. Re:To be expected by david_thornley · · Score: 1

      "Obfuscation", not "steganography".

      --
      "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
    7. Re:To be expected by itzly · · Score: 1

      I work with embedded devices. These things are limited (small battery, long life, low cost etc). Every clock tick costs power.

      State of the art ARM Cortex implementations use less power per clock tick than 10 year old 8 bit stuff, plus they do a lot more per instruction.

      Time-to-market is also important, and embedded devices are doing more and more complex tasks, so this means that your average programmer is just going to grab a couple of big libraries, instead of working out all the little details to increase performance.

    8. Re:To be expected by Anonymous Coward · · Score: 0

      Goto these days is a stenography tool...

      No, it is rarely used in court documentation.

      It might be used as a steganography tool, however.

    9. Re:To be expected by Rakarra · · Score: 1

      I'm enjoying using C again on devices with similar performance to those I was using 30 years ago (now: ATMega328P running with 1MHz CPU, ie 1 MIPS; then Z80A with 4MHz clock making for ~1MIPS) but with lots better development tools this time, and several GHz of laptop to run them on.

      I imagine being able to completely virtualize an embedded system in software on your laptop has to make the debug cycle much faster these days.

    10. Re:To be expected by DamonHD · · Score: 1

      Possibly I *could*, but as it's running on our custom hardware writing the emulation would be ... time consuming.

      But being able to bootload over serial with all the compilation (etc) happening on the laptop is still a huge boon. I still have burnt in my memory the sound of the grind grind of the floppies compiling and assembling on CPM, and with my one contact with Bill Gates (by telex) because of a boneheaded misfeature in the Microsoft tools... %-P

      Rgds

      Damon

      --
      http://m.earth.org.uk/
    11. Re:To be expected by Anonymous Coward · · Score: 0

      Not the one which are at the lower end of the power envelope.

  12. What's Unique To Goto? by Shakrai · · Score: 3

    I'm not a "hard core" coder (defined here as someone who does nothing but development) but I've been writing C for 15+ years (it was the first language I learned and remains my favorite) and have yet to encounter a situation where the use of 'goto' is a requirement or even better than the alternative. The one circumstance where I've seen it advocated is for the main loop of a long running program but I'm not certain why goto is any better than while (1) (or similar constructs) in this scenario. Correct me if I'm wrong but the main argument against goto is that it results in haphazard code that's hard to follow. I think this is true, even in the simple case of using goto to replace while (1), never mind the more convoluted examples that invariably result when goto enters the equation.

    So, people who are smarter than me, what am I overlooking? What C coding scenario presents itself where goto is the most eloquent solution?

    --
    I want peace on earth and goodwill toward man.
    We are the United States Government! We don't do that sort of thing.
    1. Re:What's Unique To Goto? by Anonymous Coward · · Score: 0

      Breaking out of a multiple-loop-nest. Other languages (e.g. Java) have labeled break/continue statements for this scenario, but in C you need to use goto if you want to break out of an outer loop from within an inner loop.

    2. Re:What's Unique To Goto? by vadim_t · · Score: 2

      Error handling with multiple instances of allocation.

      Eg, something like:

      char *buf1 = malloc(...);
      if (!buf1) goto abort1;

      char *buf2 = malloc(...);
      if (!buf1) goto abort2;

      char *buf3 = malloc(...);
      if (!buf1) goto abort3;

      return;

      abort3:
      free(buf2);
      abort2:
      free(buf1);
      abort1:
      return;

      Also, bailing out of multiple nested loops.

    3. Re:What's Unique To Goto? by vadim_t · · Score: 1

      ...and of course I messed up, that should be:

      if (!buf2) goto abort2;
      if (!buf3) goto abort3;

      The ability to edit comments would be nice.

    4. Re:What's Unique To Goto? by Anonymous Coward · · Score: 0

      I think goto is fine if the jump is not too far back or ahead, say for example if you have to get out of a nested if-else construct.
      I can recall an assignment I had to do for uni which limited what we were allowed to use and asked us to implement a way to remove dangling symlinks and empty directories.
      My solution worked flawlessly and given the circumstances I'd even consider it elegant, but I felt forced to use goto twice.
      That assignment also taught me that Linux is not POSIX compliant and that it's a bitch trying to figure out why there's a bug that shouldn't exist.

    5. Re:What's Unique To Goto? by Longjmp · · Score: 1

      Your example is just bad and exactly a reason why some people should avoid goto by all means.

      First, a 'return' between allocating memory and cleaning up? Hello memory leaks!
      Second, if you have a more complex program flow which allocates more 'bufs', do you really want 15 different gotos and labels)?
      Do you, after 6 months, remember which 'buf' is allocated where and make changes? Even more so, do you think someone else finds your code easy to understand?

      I don't mind gotos at all if used properly (e.g., cleanup) at all, so try this instead:

      (allocate memory, etc)

      if (shit_happens) goto cleanup;
      br> cleanup:
      if (buf1) free( buf1);
      if (buf2) free(buf2);
      etc...

      --
      There are fewer illiterates than people who can't read.
    6. Re:What's Unique To Goto? by vadim_t · · Score: 1

      It's pseudocode, just because something is allocated in a function doesn't mean it has to be freed right there. Though I suppose the example could be better.

    7. Re:What's Unique To Goto? by mrchaotica · · Score: 1

      First, a 'return' between allocating memory and cleaning up? Hello memory leaks!

      Yep, that's why my implementation of malloc() calls free() before returning!

      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

    8. Re:What's Unique To Goto? by Anonymous Coward · · Score: 0

      Why is it that 'while(1)' is so popular with C programmers. As far asi I know, I'm the only one that uses 'for(;;;)'. Is there some reason why people want to use 'while(1)'. I'm always worried the compiler will allocate space for a useless variable, even if it is a constant.\

    9. Re:What's Unique To Goto? by AaronW · · Score: 2

      I was forced to take the introduction to programming class in college because the Turbo Pascal program I had used a goto for this very reason. In Pascal there was no break/continue equivalent and it would have been extremely messy in the code to not use the goto.

      It later turned out that the professor did not know Pascal at all when there were simple errors in a 2 page program that she couldn't get to compile. I only showed up for the midterms and final for that useless class. The next one was worse since the professor disallowed using repeat/until, requiring recursion for everything claiming that it was just as fast since the compiler would take care of it (it wasn't, it was MUCH slower). Recursion does have it's place. Unfortunately most of the examples I see for it are places where it shouldn't be used.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
    10. Re:What's Unique To Goto? by jschultz410 · · Score: 1

      You know, not every function releases all the resources it claims before it returns. Sometimes acquiring those resources is exactly the reason why you called said function. Think of the initializer (or insertion into) of almost any kind of container data structure, for example.

    11. Re:What's Unique To Goto? by Anonymous Coward · · Score: 0

      Error handling with multiple instances of allocation.

      But you're not handling the error very well at all, your calling code has no idea you failed to allocate, or at what point you failed. I generally prefer using a switch construct for such situations:

      failcondition = 0;
      switch(failcondition){
          case 0:
              char *buf1 = malloc(...);
              if (!buf1) {failcondition = 1; break;}
          case 1:
              char *buf2 = malloc(...);
              if (!buf2) {failcondition = 2; break;}
          case 2:
              char *buf3 = malloc(...);
              if (!buf3) {failcondition = 3; break;}
          case 3:
              char *buf4 = malloc(...);
              if (!buf4) {failcondition = 4; break;}
      }

      switch (failcondition){
          case 0:
          case 1:
              break;
          case 4:
                free(buf3);
          case 3:
                free(buf2);
          case 2:
                free(buf1);
      }

      return(failcondition);

      If my resources are extremely constrained then I would consider using the goto method to make the code as lean as possible, but in the vast majority of situations that's not going to be the case, and the additional flexibility makes up for it.

    12. Re:What's Unique To Goto? by shutdown+-p+now · · Score: 1

      Recursion really depends on the language. Some of them mandate tail recursion in the language spec, for example (like Scheme), so it really is as good as a loop. For others, it's a QoI issue, like most modern C++ compilers.

      Oh, and Turbo Pascal does actually have "break" and "continue". Spelled exactly like that, too.

    13. Re:What's Unique To Goto? by AaronW · · Score: 1

      At the time I don't think it did. Recursion has its place and can be a very elegant solution. Unfortunately most examples I see showing it are better off not using it. In the language we had to use it in it didn't work well, especially since the Pascal P compiler was absolute shit and I proved beyond a shadow of a doubt why it sucks since it ran so slowly with high stack usage compared to a simple loop.

      --
      This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
  13. Safer never to use GOTO by CraigCruden · · Score: 1

    If you feel you "need" to use GOTO to make things easier, then you should take a second look at your code and invest a little time figuring out how best to reorganize your code. GOTO gives an easy out for lazy programmers who don't want to invest the time to give a little thought on how they programmed themselves into said box. In my 25 years of software development, I have never found a situation where the use of GOTO would produce better code than putting a little thought into your code.

    1. Re:Safer never to use GOTO by Anonymous Coward · · Score: 0

      Goto has nothing to do with safety. Well, in my almost 40 yrs. of software development, I've found a couple of case in C where goto leads to the cleanest code. But, of course, lesser minds like you would always find a reason too poo poo it .

    2. Re:Safer never to use GOTO by sjames · · Score: 1

      There are few cases where it is the right answer. But have a look at the Linux kernel. It is IMHO well used there.

    3. Re:Safer never to use GOTO by narcc · · Score: 1

      That's probably because you consider any code with a goto inferior to code without it. It's a no-win situation for the humble unconditional branch.

      Goto is intuitive. From CYOA books to tax form instructions, it's use is well-established in the real world. Why should developers keep to this absurd taboo just because some guy said it's bad? It makes no sense.

      In my 25 years of software development, I have never found a situation where the use of GOTO would produce better code than putting a little thought into your code.

      You'll find that you use goto quite a bit, you just don't type 'goto'. Ever use an early "return"? How about "break"? They're all goto's in disguise, letting you escape from the strictures imposed by structured programming.

      More directly, are you telling me you've never produced an ugly rats-nest of if's? I see it all the time, and lament the goto taboo. (Very often, that sort of mess is caused by a lot of little contingencies in a process, an area where goto shines. See any old tax instruction booklet.) If we still taught kids about flow-charts, they'd immediately recognize the value of the goto -- and have far better code as a result.

      Argue all you want, but lots of things are bad when misused or overused, from classes to control structures. (Nothing is safe from abuse or criticism!) We just don't have a decidedly religious taboo against them, so why single-out goto? It's actually useful, unlike other harmful things like deep inheritance hierarchies or circular dependencies. Let's focus our efforts on something more productive, and leave goto alone.

    4. Re:Safer never to use GOTO by Bengie · · Score: 1

      Goto can be better than the alternative of a bunch of 3 line functions. There are a small number of situations where attempting to not use goto makes the code harder to read.

    5. Re:Safer never to use GOTO by T.E.D. · · Score: 1

      my 25 years of software development, I have never found a situation where the use of GOTO would produce better code

      You've never written a good lexical analyzer then. No shame in that. Few people ever have to write one of those themselves. But take a look inside your (f)lex output some time. You'll find lots of gotos.

      I used to say this exact thing, until the day I came across a problem where it wasn't true. I had to recode the algorithm every way I could think of, before I could accept the truth.

      This is actually still great advice for about 95%+ of all software work. In my 30+ years of professional software development, I think I've done it once. However, if you end up in a situation where you have to code up a true state machine with no real structure to it other than nodes of code connected by control branches (eg: a lexical analyzer), then the natural expression of this is blocks of code connected with gotos. You can try and hide that by wrapping the mess in a case statement with a loop or something, but that doesn't change the real underlying control flow. In fact it *obscures* it.

      And again, this isn't me being retrograde. This is well-known among the compiler building community (where the issue comes up regularly). That's why this report was able to find so many examples. It would be a very good bet that almost all the programs it found with gotos contained lexical analyzers (eg: compilers, compiler builders, regex matchers, etc.). These people aren't unrepentant cave-men. They just know something you don't because they regularly work on types of problems you don't.

    6. Re:Safer never to use GOTO by T.E.D. · · Score: 1

      It would be a very good bet that almost all the programs it found with gotos contained lexical analyzers

      Well, I did something crazy here and actually RTFA to test my own assertion (I expect to get thrown out of /. for such heresy). I believe I would have lost my bet. There was this nifty table buried in their paper. Unfortunately, /. refuses to do tables for me, but the gist was the following goto reason distribution for files that had them:

      Error: 80.21%

      Cleanup: 40.36%

      Control-Exit: 10.16%

      Loop-Create: 8.85%

      Spaghetti: 5.99%

      Single : 54.17%

      Multiple: 62.24%

      Forward: 90.1%

      Backward: 14.06%

      Stacked labels: 26.3%

      # statements in label block (median not %): 4

      (Presumably some contradictory-looking entries here adding up to more than 100% are explained by files containing multiple gotos for multiple different purposes)

    7. Re:Safer never to use GOTO by jschultz410 · · Score: 1

      Really? How else do you handle error conditions and stack unwinding in C? I'd love to see you write a function that needs to acquire N resources (say N distinct mallocs) where any one of the acquisitions can fail and do it more cleanly than an approach that uses goto's to implement explicit stack unwinding in an error condition.

    8. Re:Safer never to use GOTO by angel'o'sphere · · Score: 1

      Ugly rats nests of ifs can always be refsctored with the 'extract function' (extract method) refactoring.

      In modern IDEs for Java/C# you only selcet the relevant code block and select the command and the IDE does that for you.

      Sorry, I did not work in a single company the last 20 years where braces more than two levels deep in any piece of code where allowed by coding guidelines.

      Please show me an example of deep neseted ifs and the unit tests to it ... I quickly show you which statement(s) is(are) not tested and why.

      We don't live in 1MHz 8Bit times anymore. Every fool can write code a compiler can compile. Writing code for humans to understand is the issue.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  14. Limited sample :) by davidwr · · Score: 4, Funny

    I bet the "valid random sample" didn't include any projects from the Obfuscated C Code Contest.

    --
    Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
  15. Makes sense. by Anonymous Coward · · Score: 1

    (Warning: Olde Phart story here.)

    Years ago in a previous life, I programmed in FORTRAN III and IV, with lots of GO TO statements. Later, when I had access to FORTRAN 77 with Vax extensions, the need for GO TO statements went away. So I took one of my programs (~2000 lines, IIRC) and rewrote it using the "GO TO" - free logic, and lo and behold I didn't have to move or rearrange even ONE line of code.

    Folks, it's not the GO TO that is the problem, it's sloppy and disorganized thinking that leads to spaghetti code.

    (All you kids, GET OFF MY LAWN!)

    1. Re:Makes sense. by rujasu · · Score: 1

      Good coders can definitely mitigate the risk of goto statements. However, goto makes it easier to really screw things up if you don't 100% know what you're doing, or if you make a mistake.

  16. Re:GOTO is a crutch for bad programmers by adonoman · · Score: 4, Informative
    What would you propose as a better alternative to this idiom in a language that lacks exceptions:

    void func() {
    if (!AquireResource1()) goto end;
    if (!AquireResource2()) goto cleanup1;
    if (!AquireResource3()) goto cleanup2:

    DoStuffWithResources();

    Cleanup3();
    cleanup2:
    Cleanup2();
    cleanup1:
    Cleanup1();
    end:
    return;
    }

  17. Goto fail; by Anonymous Coward · · Score: 0

    Apple devs, get in here!

    1. Re:Goto fail; by Anonymous Coward · · Score: 0

      goto hell;

    2. Re:goto fail; by marka63 · · Score: 1

      Are you saying that you would have caught the error if it was "return err;" instead of "goto fail;"?
      Do you want to ban "return" next?

      int err;
      if ((err = PrepareHash(x,n)) != 0)
              return err;
              return err;
      if ((err = CalculateHash(x,n)) != 0)
              return err;
      return CompleteHash(x,n);

      In both cases there is code that is unreachable and a good dead code analysis will catch it.

    3. Re:goto fail; by andyhhp · · Score: 1

      This is a muppet misusing if(), not misusing goto.

  18. That's because of "Goto Considered Harmful" by Todd+Knarr · · Score: 1

    That result's because programmers got the ideas in "Goto Considered Harmful" pounded through their skulls while they were learning, and handled it like they would dynamite: it's very effective and the best tool for certain jobs, but it's also very dangerous and capable of causing a ton of damage so you should handle it with an abundance of caution. tl;dr: "Use it to crack huge boulders and tree-stumps, not to loosen bolts."

    1. Re:That's because of "Goto Considered Harmful" by mariox19 · · Score: 1

      I agree. The sample is self-selecting, because by and large the only people using it are the ones who fully understand why using it in certain cases is not only not harmful but actually maybe even better. How about we tell CS students to use it whenever they feel like, but just be careful; we then wait, say, 10 years or so and run the study a second time?

      My guess is the conclusion that time around would be: Goto responsible for the fall of Western Civilization.

      --

      quiquid id est, timeo puellas et oscula dantes.

  19. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    No it's not. Bad programmers, like you, blame the language features for their crappy code.

  20. Outdated... by The+New+Guy+2.0 · · Score: 1

    "GOTO" existed before subroutines and functions were added, and it was back in the days of line numbers. This was the point where the main menu part of a program had to jump over to the appropriate part of the program, now we just call the appropriate routine.

    1. Re:Outdated... by Trailer+Trash · · Score: 1

      "GOTO" existed before subroutines and functions were added, and it was back in the days of line numbers. This was the point where the main menu part of a program had to jump over to the appropriate part of the program, now we just call the appropriate routine.

      But more than that, GOTO is how processors work at the lowest level. All of those fancy blocks in a modern language get turned into "jumps" and such at the lowest levels when compiled. The first computer languages - such as fortran - were a pretty thin veneer over assembly, anyway, so gotos made sense.

    2. Re:Outdated... by bobbied · · Score: 1

      "GOTO" existed before subroutines and functions were added, and it was back in the days of line numbers. This was the point where the main menu part of a program had to jump over to the appropriate part of the program, now we just call the appropriate routine.

      GOTO predates just about everything but the CPU. It's a mirror of the "Jump to:" machine instruction that is common to EVERY Processor I've ever seen.

      --
      "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
    3. Re:Outdated... by The+New+Guy+2.0 · · Score: 1

      GOTO makes sense at lower-level languages closer to the processor, but in languages based on procedures and subroutines they lead to harder for humans to understand code.

  21. 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
    1. Re:Way to bury the lead by DamonHD · · Score: 1

      Bingo: you win tonight's Internets...

      Rgds

      Damon

      PS. Like all that Y2K work I wasn't doing in a bank that wasn't necessary except that it was...

      --
      http://m.earth.org.uk/
    2. Re:Way to bury the lead by GerardAtJob · · Score: 1

      So true, but out of mod points :D
      And yes... I read at -1 too :)

      --
      I can't call that English ;-)
  22. Re:GOTO is a crutch for bad programmers by DamonHD · · Score: 1, Funny

    Some sort of nested do { ... } while(false); and break; would be my first suggestion.

    Rgds

    Damon

    --
    http://m.earth.org.uk/
  23. Re:GOTO is a crutch for bad programmers by MightyYar · · Score: 1

    It's even worse, but it avoids the word "goto" (while still being a goto IMHO):

    while(1) {
        if (!AquireResource1()) break;
        DoStuffWithResources();
        break;
    }
    Cleanup();

    --
    W..w..W - Willy Waterloo washes Warren Wiggins who is washing Waldo Woo.
  24. Still Harmful by medv4380 · · Score: 1

    Goto messes with readability and long term maintenance. Anyone who uses Goto is probably going to use it correctly. Otherwise you wouldn't use it. But you use it to construct loops, and functions which is unnecessary and illegible compared to every other option.

  25. Re: GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Cleanup resources using destructors, use a plain return on failure.

  26. Blocks considered harmless by Marginal+Coward · · Score: 2

    It's no surprise that goto's are used sparingly - and generally only with very good reason - by modern programmers. Dijkstra's paper is dated 1968, which is about the time ALGOL was invented. ALGOL which was the first block-oriented language. Heck, maybe its design was even influenced by Dijkstra's paper - who knows?

    Given a language that supports blocks (and all modern languages do), there's little reason to use gotos. Instead, you use blocks and related goto-like constructs such as break, return, try/catch, etc. Anything but a literal goto.

    IIRC, the CPython source code has a few goto's in it. I remember that Tim Peters once defended that as being the best solution (in C, at least) for certain very exceptional situations. It's no coincidence that they're used very, very sparingly there. And maybe they wouldn't be needed at all in CPython if C had a try/catch construct - like Python itself.

    In my own case, I've used them mostly when transliterating some ancient FORTRAN code into C. Rather than untangling the code into blocks, it was simply easier to replicate the goto's. At the time, I actually had to consult K&R to brush up on C's goto syntax. Also, the FORTRAN code I was working with was proven and needed little maintenance, so removing the goto's was more likely to make it worse than to make it better.

    1. Re:Blocks considered harmless by Marginal+Coward · · Score: 1

      Correction: I see now on Wikipedia's ALGOL page that blocks were introduced in ALGOL in 1960. So maybe ALGOL influenced Dijkstra rather than the other way around.

    2. Re:Blocks considered harmless by Anonymous Coward · · Score: 0

      Oh, why do you have to mention old fortran code... F77 is so awful that the use of GOTOs is the least of your problems.

      When you're dealing with "language expects you to use global variables" and "language has no malloc or heap", that tangled Elder God-like mass of gotos that's supposed to somehow solve the Poisson equation (except it doesn't) is the least of your worries.

    3. Re:Blocks considered harmless by edtice1559 · · Score: 1

      Try/catch is a great solution. Too bad the designers of the C language didn't include it. Who were those guys again?

    4. Re:Blocks considered harmless by Anonymous Coward · · Score: 0

      > ALGOL which was the first block-oriented language. Heck, maybe its design was even influenced by Dijkstra's paper - who knows?

      Wikipedia knows and lists Dijkstra as author of the X1 ALGOL 60 and Burroughs ALGOL _implementations_.

    5. Re:Blocks considered harmless by shutdown+-p+now · · Score: 1

      Algol had blocks (and, more importantly, loops, quite fancy ones too) - but it didn't have anything similar to "break" or "continue", and you had to use boolean flags or goto for that.

      It had some crazy stuff in the goto department, too. For example, you could pass labels as parameters to functions, and they could then goto a parameter to jump out (possibly unwinding several stack frames in the process).

    6. Re:Blocks considered harmless by shutdown+-p+now · · Score: 1

      BTW, here is the Algol-60 standard. It's pretty short, so should be an easy read, but if you haven't seen it before, you'll be surprised at how much was there already, given that we're talking about something that started its life in 1958 (that's when the first Algol report was published, 1960 was a later revision).

  27. Re: GOTO is a crutch for bad programmers by Nemyst · · Score: 1

    Destructors? This isn't C++.

  28. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 2, Interesting

    void func() {
    if (AquireResource1()){
    if (!AquireResource2()){
    if (!AquireResource3()){

    DoStuffWithResources();
    Cleanup3();
    }
    Cleanup2();
    }
    Cleanup1();
    }
    return;
    }

  29. This is C, not C++ by mveloso · · Score: 1

    "Cleanup resources using destructors"

    Good luck with that.

  30. Re:GOTO is a crutch for bad programmers by Shakrai · · Score: 1

    void func () {
    if (!AquireResource1()) return;

    if (!AquireResource2()) {
    Cleanup1();
    return;
    }

    if (!AquireResource3()) {
    Cleanup2();
    Cleanup1();
    }

    DoStuff();

    Cleanup3();
    Cleanup2();
    Cleanup1();
    return;
    }

    --
    I want peace on earth and goodwill toward man.
    We are the United States Government! We don't do that sort of thing.
  31. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 4, Informative

    Fundamentally, that *is* a GOTO. It's just a less-readable idiomatic GOTO that doesn't include the "goto" keyword.

  32. It WAS harmful in practice until ... by jma42 · · Score: 0

    I wish I could show you some code that I and others had written in the late sixties and early seventies. The term "Spaghetti Code" was invented to describe the flow charts that were made to document the code. Those charts actually looked like a bowl of spaghetti. There's nothing like it today.

    Maintaining code like that was some of the most tedious and frustrating (and sometimes fruitless) work I've ever done.

    That all changed with the invention of structured programming (which, btw, does NOT mean "top-down modular"). Today, everyone writes structured code, though they don't know it. But at the time, it was revolutionary. There were even reactionaries who folded their arms and staunchly refused to ever code that way.

    When I first learned it, my whole world view changed. Coders were walking around with glassy eyes, amazed that the world had changed so quickly. You have no idea.

    Structured programming was the first systematic rejection of goto statements. But even then, it wasn't total. Gotos were still allowed for error conditions. They said, "When there's an error, anything is allowed".

    --
    OKsofar
  33. Re:GOTO is a crutch for bad programmers by Shakrai · · Score: 2

    Overlooked the return in my third if statement, but you get the idea....

    --
    I want peace on earth and goodwill toward man.
    We are the United States Government! We don't do that sort of thing.
  34. Breakpoints by tepples · · Score: 2, Informative

    It turns out that many CPUs have hardware support for comefrom, usually to support debuggers. For instance, x86 has DR0, DR1, DR2, and DR3. And that's the only place I'd use a comefrom: as a debugging breakpoint.

    1. Re:Breakpoints by Austerity+Empowers · · Score: 0

      Almost all modern CPUs have comefrom. It's always used in regular operation on "ret" or workalike instructions, to return to where you come from!

  35. Re: GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Okay, then I'd recommend C++.

    It's so close to a strict superset that I don't think that's an unreasonable response.

  36. Equally stupid dogma by Anonymous Coward · · Score: 0

    Similarly stupid C/C++ dogma:


    • Macros are dangerous.
      Function pointers are unsafe (MISRA).
      Multiple inheritance is bad.
      Heap allocation is unsafe.
    1. Re:Equally stupid dogma by goose-incarnated · · Score: 1

      Similarly stupid C/C++ dogma:

      • Macros are dangerous.

      They can be. They can also be a boon to your custom logging facility like this:
      #define LOG(x,...) logfunc (__FILE__, __LINE__, __func__, x, __VA_ARGS__);

      ...
      size_t size_t_var;
      char * char_ptr_var;

      ...
      LOG ("Free-form logging, using %zu and %s free formats\n", size_t_var, char_ptr_var);

      Function pointers are unsafe (MISRA).

      They are for certain segmented/banked memory platforms (yes, I worked on a weird motorola chip once with banked memory). Casting a void pointer to a function pointer resulted in the correct address but in the wrong bank! In any case, MISRA has a more than few stupid rules - I think this rule came about in the days of banked memory and C89 not defining the results of casting a function pointer to any other pointer and back again. Hell, this one might even predate that all the way to K&R C.

      Multiple inheritance is bad.

      No opinion on this one.

      Heap allocation is unsafe.

      Once again it depends. I've spent a large part of my life writing code for tiny little processors with limited memory. The general rule, especially for the military stuff, is that you are not allowed to run out of memory while executing. So either your binary image fits on your device after compilation or it doesn't. It must not fit, and then run out of memory days later during execution. The only way to ensure this in a formal manner is to have no malloc or equivalent calls.

      --
      I'm a minority race. Save your vitriol for white people.
    2. Re:Equally stupid dogma by bobbied · · Score: 1

      However, when properly used, NOTHING is faster or has a smaller memory footprint. There ARE reasons for this stuff...

      --
      "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
    3. Re:Equally stupid dogma by grimmjeeper · · Score: 1

      Once again it depends. I've spent a large part of my life writing code for tiny little processors with limited memory. The general rule, especially for the military stuff, is that you are not allowed to run out of memory while executing. So either your binary image fits on your device after compilation or it doesn't. It must not fit, and then run out of memory days later during execution. The only way to ensure this in a formal manner is to have no malloc or equivalent calls.

      That's a pretty standard rule in any safety critical environment. You see this in civilian avionics, medical devices, etc. Dynamic allocation is nondeterministic so it's not safe. You pre-allocate everything you need and manage it with deterministic management functions with predictable error handling. Of course, one could argue that you can embed your malloc() in good error handling functions that deal with failure in a deterministic way and you're still safe. However, the dogmatic approach to malloc usually means you usually lose that argument.

    4. Re:Equally stupid dogma by goose-incarnated · · Score: 1

      To be perfectly honest, I didn't see the point. Yeah, sure, malloc means that we're going to fragment memory until a malloc that worked the last 5 million times is going to fail because the biggest free block is smaller than the requested size. I understand that bit perfectly well.

      The puzzler is the lack of restrictions on function-call depth, of if there were restrictions then the lack of enforcement of the restriction. I suppose that it's because it gets exponentially more difficult (towards infinity, actually) to determine if a call-path exists that will overflow the stack.

      Actually, ISTR a compiler from the 90's - cosmic for MCu's - that enforced function call depth, although it may have been a static compile-time check. Once running no automated system can predict how high the stack will grow.

      --
      I'm a minority race. Save your vitriol for white people.
    5. Re:Equally stupid dogma by grimmjeeper · · Score: 1

      In all of the avionics systems I worked on, we had a rule against recursion (direct or indirect), variable argument lists, etc. Every task had a static analysis performed on it to determine maximum stack usage. The stacks were fitted to the usage. Without recursion or any other goofy stuff like that, it wasn't hard to do a call trace and add up all of the parameters in the calls to ensure you always had enough stack space. And that code is flying all over the world with not one stack overflow.

      Now, if you actually have use of the full language to do as you want when developing the software, stack analysis very quickly becomes difficult or harder. But when you're writing code that has to work or the plane hits the ground and people die, they get a little picky about how you do it.

    6. Re:Equally stupid dogma by mrchaotica · · Score: 1

      Heap allocation is unsafe.

      Once again it depends. I've spent a large part of my life writing code for tiny little processors with limited memory. The general rule, especially for the military stuff, is that you are not allowed to run out of memory while executing. So either your binary image fits on your device after compilation or it doesn't. It must not fit, and then run out of memory days later during execution. The only way to ensure this in a formal manner is to have no malloc or equivalent calls.

      For that, "no heap allocation" is necessary but not sufficient. You also need to prove that your stack doesn't overflow.

      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

    7. Re:Equally stupid dogma by angel'o'sphere · · Score: 1

      Why dynamic allocation is claime dto be nondeterministic is beyond me.

      It is a function call like anything else. You know when the function is called and why.

      It is fucking no difference, if I have preallocated everything and when I get to much data to process I drop some data, or if I want to allocate memory for to much data and have to drop it because I have no memory.

      The reason why some systems don't use alloc/malloc has nothing to do with deterministics or what ever. Perhaps it is simpler to 'proof' (for simple minded gys) that they behave correct. But thats it.
      Bottom line there is no difference at all if you manage you fixed amount of RAM by accessing it via static variables or if you use dynamic allocation. In the later case you can use the system more effectively and can allocate memory to taks that need it (and release it for other tasks later). In the former case all tasks are limited to a fixed limit.

      The firmer is easy for mediocre programmers. The later is no problem at all for competent programmers. However it turns out the later is on modern hardware rarely needed. Calling that the holly grale of programming (not using malloc) is just absurd. How can something that is simpler be proclaimed more difficult!

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    8. Re:Equally stupid dogma by grimmjeeper · · Score: 1

      There's one reason it's considered nondeterministic. Memory leaks. If you have a task that has a bug that leaks memory, the system will eventually run out of space and that will impact normal function. That's not a huge issue on a desktop that's running Word, Excel, and solitaire. You can just kill the offending application and restart it. But you absolutely can't do that in a safety critical embedded system. You can't just reboot the flight control software on an airplane in mid flight. You can't just reboot the heart-lung machine in the middle of an operation. It has to work. Period.

      By preallocating what each individual function needs ahead of time and forcing it to remain within the confines of that space, you eliminate any chance of a rogue function taking the whole system with it as well as being able to more easily build functions that can recover from a failure. It's about reducing risk and reducing the damage caused by failure. "Oh, my allocation of some memory failed? Let me scan the little bit of what's set aside for me to make sure I disposed of everything properly or if I really am overflowing my constraints and need to follow the prescribed method for recovering from that overflow."

    9. Re:Equally stupid dogma by angel'o'sphere · · Score: 1

      Erm, flight computers are rebooted during flight routiniously.

      Heart Lung machines hardly need special software. They get started before operations start, and get shut down afterwards and started/rebooted next time they are needed.

      Memory leaks are a problem, obviously, that can be avoided by not using alloc/free, obviously.

      Stating obvious stuff does not break a lance for that case. The simplest reason why embedded systems often don't use alloc/malloc/free is: they don't need to. You simply only use global variables and thats it. Wow: instead of proclaiming it to be an art, it actually is the lowest complexity level of programming in existing :)

      Yeah, sorry if you are an embedded programmer and you always thought you where the king of coding. You are not.

      Invent/code a kernal, or a data base ... much more challenging than avoiding an alloc in a stupid read sensor, calculate action, trigger actor loop (aka heart/lung machine).

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  37. Re:GOTO is a crutch for bad programmers by loonycyborg · · Score: 1

    Actually you could split off each resource acquisition into separate function that does acquire -> check -> cleanup cycle for one resource and calls next function in chain. Not shorter than goto way but you're less likely to shoot yourself in the foot by messing up order of cleanups or something.

  38. Re:GOTO is a crutch for bad programmers by DaphneDiane · · Score: 1

    Comment.c:12: Warning missing return before }

  39. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    I mean this.

    void func() {
    if (AquireResource1()){
    if (AquireResource2()){
    if (AquireResource3()){

    DoStuffWithResources();
    Cleanup3();
    }
    Cleanup2();
    }
    Cleanup1();
    }
    return;
    }

  40. No one is using GOTO because .... by 140Mandak262Jamuna · · Score: 1
    If you check present day code you won't see much use of GOTO. That is because the programmers have found an even more nefarious and orders of magnitude worse construct, COMEFROM statement.

    Really this is a COMEFROM statement, no?

    bool OnRightButtonClickCallBack(void *a, void *b, void *c){

    int xx=int(a);

    int yy=int(b);

    global_window *gw=(global_window *) c;

    ...

    ...

    }

    --
    sed -e 's/Chuck Norris/Rajnikant/g' joke > fact
    1. Re:No one is using GOTO because .... by Anonymous Coward · · Score: 0

      Thrown an exception in there and I think you nailed it.

    2. Re:No one is using GOTO because .... by rujasu · · Score: 1

      And why do you think this is bad practice?

  41. A case against GOTO by Anonymous Coward · · Score: 0

    Wasn't it Vint Cerf who redacted "A case against GOTO" to the phrase we all know?

    1. Re:A case against GOTO by narcc · · Score: 1

      That was Niklaus Wirth.

  42. To simulate exception handling by tepples · · Score: 2

    Goto is easy to avoid, and is a symptom of a poorly designed program.
    [...]
    I have occasionally used goto as a quick hack, usually to handle error conditions.

    In languages with exceptions, one uses a finally clause (or a C++11 scope guard) to perform cleanup, such as releasing memory or non-memory resources that a function owns. In C, one uses goto to jump to the cleanup code if it detects an exceptional condition. Or is a program that needs to do this sort of cleanup "poorly designed" solely on account of being implemented in C instead of a language with language-level exceptions?

    When I later go back and refactor the code, it is always cleaner and more readable without the goto.

    By "refactor" do you mean "rewrite in C++"? If not, could you give an example of such a refactoring?

    1. Re:To simulate exception handling by Anonymous Coward · · Score: 0

      Actually setjmp and longjmp would be the direct equivalent of exception handling in C. goto is function local and doesn't allow jumping out of functions.
      If error handling can be handled with goto rather than exceptions it tends be be a lot cleaner since it's not always obvious how far out an exception will take you.
      Of course exception handling in C++ is a bit safer than longjmp since the syntax prevents you from doing the jump in a way that screws up your stack but the performance cost is a bit more obvious in C.

  43. What's the term for a prophylactic prediction? by Anonymous Coward · · Score: 0

    Some/many languages in 1968 didn't have 'modern' control structures like while() for() etc. Or the ability to group lines of code. In this case it's not really the goto that is bad, it's the lack of features that is bad. This is so obviously bad it's not worth commenting on.

    The real reason Dijkstra hated goto is it made it impossible to write 'proofs' about programs. IE, prove the program or algorithm is correct. So his hope was by restricting the grammar programs so written could be mathematically proved. Pascal I believe was also written with the idea that formal proofs were important. Suspect Java followed on the basis of cargo cult compiler design. No goto or unsigned integers for you.

    Either way, except in narrow cases, such proofs are essentially impossible. And computer scientists gave up around 1980. However the cargo cult still exists telling generations of programmers that goto, continue, and multiple returns are shameful.

  44. #1 use for goto in c by Anonymous Coward · · Score: 0

    // This especially becomes important when you have many nested loops
    bool endloop = false;
    while(condition())
    {
            if(endloop) break;
            while(condition2())
            {
                    if(endloop) break;
                    while(condition3())
                    {
                            if(condition4())
                            { // I want to break out of all loops here. // I could make a variable to incrementally // break out of the loops one by one like so
                                      endloop = true;
                                      break; // or I could do the following and get rid of the endloop variable completely:
                                      goto exitloop;
                            }
                    }
            }
    }
    exitloop: // Rest of code

    1. Re:#1 use for goto in c by Ark42 · · Score: 1

      I still don't get why modern languages don't include an optional numeric for "break" statements. A simple "break 3;" would be a lot better than a "goto".

    2. Re:#1 use for goto in c by grimmjeeper · · Score: 1

      There is a good case for moving that nested loop into its own function. At that point, you put in a return instead of a goto. Though the number of arguments to the new subfunction may be an argument against doing it that way.

      Another thought would be putting the "rest of code" in its own function and calling that function inside the "if(condition4())". Again, it depends on local variables and how many would have to be set up as arguments.

      To be concise, however, I would merge the "if (endloop)" into your while conditionals. i.e. "while(!endloop && condition2())". That condenses the code a little without losing any readability.

    3. Re:#1 use for goto in c by frank_adrian314159 · · Score: 1

      Because experience has shown (a) it's not been used much when available because people aren't used to using it and (b) people don't use it because it makes the code fragile. Why? Because changes in the block structure of the code through which the break travels can potentially break the break. This becomes worse the higher the number of the break becomes. And, more to the point, these jumpings back to the wrong level of code tend to introduce subtle errors in already deeply-nested code which is hard enough to debug. It's been tried. It's a bad idea as a general construct.

      --
      That is all.
    4. Re:#1 use for goto in c by Anonymous Coward · · Score: 0

      Yes, soon as you include lots of variables, your solution wont work. You are correct about merging the variable, but I still find gotos the cleanest solution for very high nested loops

    5. Re:#1 use for goto in c by DreamMaster · · Score: 2

      What I would have loved to see in C would be a different keyword for break for exiting a loop versus ending a switch case. 90% of the times in recent years that I've been tempted to use goto have been when I've written a switch statement in a loop, and need to break out of the loop from one of the cases. I have to steel myself and either rewrite the particular case as an if statement before the switch (nasty), or fiddle around with flags to break out of the loop after the switch statement, or check it as part of the loop condition.

    6. Re:#1 use for goto in c by narcc · · Score: 1

      Why?

    7. Re:#1 use for goto in c by mrchaotica · · Score: 1

      Though the number of arguments to the new subfunction may be an argument against doing it that way.

      If your function takes too many arguments, then you're probably suffering from a lack of encapsulating data structures (or trying to do too much in one function).

      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

    8. Re:#1 use for goto in c by grimmjeeper · · Score: 1

      That's very likely. But sometimes there's only so much you can reduce a problem and there's just too much data interacting that you can't simplify it further. And realistically, sometimes you have to work in an environment where the data models haven't been created to be very elegant at handling the intended use of the data. I don't think I've ever worked on any system with more than trivial complexity that couldn't stand to have it's data models refactored.

    9. Re:#1 use for goto in c by mrchaotica · · Score: 1

      You can always turn

      ret_type function_1(type1 param1, type2 param2, ... typeN paramN) {...}

      into

      typedef struct function_1_params {
      type1 param1;
      type2 param2;
      ...
      typeN paramN;
      } function_1_params;

      ret_type function_1(function_1_params params) {...}

      In fact, you would (ideally) notice that the params in your struct have something in common (other than merely being arguments of the same function), name your struct accordingly, and then start using it in other places where it makes sense. You can also even group your N arguments into M structs, where 1 < M < N and the arguments within each group are more related to each other than to the arguments in the other groups.

      --

      "[Regarding the 'cloud,'] ownership was what made America different than Russia." -- Woz

    10. Re:#1 use for goto in c by grimmjeeper · · Score: 1

      That's one way to do it. But when you're working on big classes with huge copy constructors (or even just big arrays or structures), it's not as practical. Maybe making a structure full of pointers could work better. But it's still a lot of overhead that increases complexity for no real gain. You'd quickly hit the point of diminishing returns. I would say that if you get to the point where you need a structure to hold all of those parameters, you've gone well past the point where the GOTO is appropriate, more efficient and easier to read.

      I'm really not a fan of the GOTO but if you're spending a dollar to save a dime, you're better off just using the GOTO.

    11. Re:#1 use for goto in c by angel'o'sphere · · Score: 1

      Java does that, but uses a label. I believe C# does somas well.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    12. Re:#1 use for goto in c by angel'o'sphere · · Score: 1

      I'm fully with you!

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    13. Re:#1 use for goto in c by Anonymous Coward · · Score: 0

      > A simple "break 3;" would be a lot better than a "goto".

      No. It would be a lot worse.

      The problem with goto is not the goto itself which is quite clear what will happen. The problem lies with the label that is required. Examining code at the label does not show all the logic paths. It is necessary to examine the whole scope of the label to determine all possible paths of flow. At least the label gives a warning that there may be non-obvious flow.

      Your suggestion of break n; does not need a label so there is _no_ warning that non-obvious flow will occur.

      It would also be a bug factory because adding an extra layer of looping would probably require changing the n (to break 4;) but this would require examining every line, whereas at least the goto would still work correctly (as would a break; at each level).

    14. Re:#1 use for goto in c by shutdown+-p+now · · Score: 1

      Or you could use goto :)

      (just like you would if you had to break out of two or more levels of nested loops)

  45. Re:GOTO is a crutch for bad programmers by MagickalMyst · · Score: 1

    "What would you propose as a better alternative..."

    A switch/case statement, or function calls.

    Using "goto" is akin to using global variables, imho.

    --
    Political correctness is really just herd psychology pushed by insecure people who desperately seek social conformity.
  46. goto for coroutines by tepples · · Score: 1

    Because if you use goto in a class assignment, you lose points.

    If the assignment is "Implement a coroutine mechanism for C", why would a sane instructor dock the student for making something like this clear wrapper around goto ?

    1. Re:goto for coroutines by DreamMaster · · Score: 1, Offtopic

      If anyone's particularly interested in coroutines, we in the ScummVM project, which provides a reimplementation of lots of old classic adventure games, implemented a fairly clean C++ coroutine implementation, which we already use for two different games were originally threaded. ScummVM runs on a variety of different hardware, not all of which support threading, so we had to come up with a way to run these games using only a single thread. See https://github.com/scummvm/scu... and coroutines.cpp if you're interested.

  47. Re:GOTO is a crutch for bad programmers by itzly · · Score: 2, Interesting

    I find the gotos easier to read than the nested set of if statements. Especially because the gotos are a well known idiom for handling this type of error/cleanup.

  48. Re:GOTO is a crutch for bad programmers by MagickalMyst · · Score: 1

    Fundamentally, perhaps, but in actuality, no.

    If there is no goto keyword then there is no goto usage.

    --
    Political correctness is really just herd psychology pushed by insecure people who desperately seek social conformity.
  49. Re:GOTO is a crutch for bad programmers by psmears · · Score: 1

    What would you propose as a better alternative to this idiom in a language that lacks exceptions:

    I propose this; namely using variables to keep track of the state of resources, and then cleaning up based on the values of those variables. In my experience this is much less error-prone than the "goto" equivalent - for example, reordering the code is much less likely to break the cleanup.

  50. Re:GOTO is a crutch for bad programmers by itzly · · Score: 2

    That's horrible with the code duplication. It gets even worse if the cleanup is 2 or 3 lines per resource.

  51. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 1

    I think one is a fool for not using available commands just because they can be misused. There's absolutely nothing wrong with a goto in and of itself, only the logic issues it may cause in improper use. Sure, you may not like goto and you are free not to. But to make all this noise about it's existence is plain silly.

    Kind of like how some people stick with the original version of vi because of some fear of change, or whatever drives them. They are free to but to oppose improvement rather than just ignoring it is also silly. Not everyone want to be stuck having to press i for insert every time the cursor lands in the first column.

    Now if you don't have much of a life with enough challenges ...

  52. Re:GOTO is a crutch for bad programmers by DamonHD · · Score: 2

    The key virtue, such as it is, of the do { ... } while(false), better wrapped up in a macro, is that it makes it harder to get the nesting wrong by accident, which is critical.

    With goto there is no such safety net.

    But I think we're agreeing furiously.

    Rgds

    Damon

    --
    http://m.earth.org.uk/
  53. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Fixed...

    void func() {
      if (AquireResource1()) {
        if (AquireResource2()) {
          if (AquireResource3()) {
            DoStuffWithResources();
            Cleanup3();
            }
          Cleanup2();
          }
        Cleanup1();
        }
      return;
    }

  54. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0


    void func() {
    if (AquireResource1())
    {
        if (AquireResource2())
        {

          if (AquireResource3())
          {
              DoStuffWithResources();
              Cleanup3();
          }
          Cleanup2();
      }
      Cleanup1();
    }
    return;
    }

    There are places to use goto, but this isn't one of them

  55. Re:GOTO is a crutch for bad programmers by Your.Master · · Score: 1

    void func()
    {
            if (AquireResource1())
            {
                    if (AquireResource2())
                    {
                            if (AquireResource3())
                            {
                                    DoStuffWithResources();

                                    Cleanup3();
                            }
                            Cleanup2();
                    }
                    Cleanup1();
            }

            return;
    }

    I know some people are allergic to triangles, but I like them because it makes it easy to see what code is potentially skipped and which code is definitely going to run (barring a crash) at any given time.

    Another alternative:

    void func ()
    {
            Resource resources[3];
            if (AcquireResource1(&resources[0]) &&
                AcquireResource2(&resources[1]) &&
                AcquireResource3(&resources[2]))
            {
                    DoStuff(Resources);
            }
            ReleaseResources(resources);
            return;
    }

    This is essentially simulating RAII semantics in C. You might even pack all three AcquireResource[1|2|3] functions into a common AcquireAllResources and in so doing make the if less ugly.

    I don't like that goto code above because I think it makes it difficult to follow every flow of execution. You may be used to it and think the opposite.

  56. Both kinds of ALTER are still in use by tepples · · Score: 1

    What kind of ALTER statement are you imagining?

    • SQL has ALTER TABLE to add a column to a relation or change the data type in an existing column.
    • COBOL has ALTER X TO PROCEED TO Y. Nowadays they call this a callback, where X is a "function pointer" and Y is a "delegate", "command object", "closure", or whatever.
    1. Re:Both kinds of ALTER are still in use by Anonymous Coward · · Score: 0

      > COBOL has ALTER X TO PROCEED TO Y. Nowadays they call this a callback [wikipedia.org], where X is a "function pointer" and Y is a "delegate", "command object", "closure", or whatever.

      No. Not even close. What COBOL ALTERs is a GO TO, which is nothing like a function call. In particular, if a call of a function has a callback parameter then that callback is executed and the program resumes after the call. An ALTERed GO TO may never be executed or it may be ALTERed again before being executed.

    2. Re:Both kinds of ALTER are still in use by tepples · · Score: 1

      What COBOL ALTERs is a GO TO, which is nothing like a function call. In particular, if a call of a function has a callback parameter then that callback is executed and the program resumes after the call.

      True, function call semantics aren't exactly the same as a flat-out GO TO. But a tail call, or function call immediately followed by a return, is semantically the same as a GO TO, and compilers for functional programming languages are generally required to optimize it as such.

      In any case, COBOL has the PERFORM statement to call a function. Can PERFORM be ALTERed in the same way? If not, you can make a paragraph that contains only a GO TO, ALTER that GO TO to point at a given function, and then PERFORM that. Thus that paragraph would become your function pointer.

      An ALTERed GO TO may never be executed or it may be ALTERed again before being executed.

      Likewise, a function pointer variable that has been assigned may never be called or it may be assigned again before being called.

    3. Re:Both kinds of ALTER are still in use by Anonymous Coward · · Score: 0

      > In any case, COBOL has the PERFORM statement [mainframegurukul.com] to call a function.

      No. PERFORM does not 'call a function'. It does 'execute a procedure' but that is not the same in a number of ways. COBOL uses CALL to call a function.

      > Can PERFORM be ALTERed in the same way?

      No.

      > If not, you can make a paragraph that contains only a GO TO,

      Actually it is only possible to ALTER a GO TO that is in its own paragraph because the statement is 'ALTER paragraph TO GO TO some-other-label'.

      > ALTER that GO TO to point at a given function, and then PERFORM that. Thus that paragraph would become your function pointer.

      No. Wrong. It wouldn't return and thus is nothing like a function. PERFORMing a paragraph with a GO TO in it (only) is equivalent to just doing the GO TO, it doesn't return.

  57. 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.

  58. What's Unique To Goto? by Anonymous Coward · · Score: 0

    A good case is where you need to break out of a complex block of code and do some clean up before the return. Like freeing memory or file handles. I also recently had a case where goto really simplified a bunch of nested if statements. Another case is inside state machines build around a switch() statement.

    You can have.

      CASE_BLAH:

        label_blah;

    The main reason for that is to get rid of complicated duplicate code. Mainly because having two bits of code that should be identical, but isn't quite results in maddening bugs.

    In general I think, if the goto it tranfering control forward it tends to be 'okay' goto's transferring control backwards is suspicious.

  59. Even that is more readable if it's re-written by davidwr · · Score: 1

    FART: printf("FART\n"); goto FART;

    OK fine do it this way if you are using BASIC or some other language where GOTO is a common idiom.

    But in most common procedural languages something akin to

    while (true) do print("FART\n") ; done

    or

    do print("FART\n") until (false)

    is easier to read, if only because you don't have to remember that lines can have labels.

    --
    Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
    1. Re:Even that is more readable if it's re-written by Culture20 · · Score: 1

      I was just pointing out that most uses of goto (in any language) are childish infinite loops that pose no danger. This would skew the results of the study unless they ignored these as being trivial use.

    2. Re:Even that is more readable if it's re-written by Anonymous Coward · · Score: 0

      I was just pointing out that most uses of goto (in any language) are childish infinite loops that pose no danger.

      If you actually read the summary, you'd have read:

      we find that developers limit themselves to using goto appropriately in most cases,

    3. Re:Even that is more readable if it's re-written by Culture20 · · Score: 1

      And my point is that a simple infinite loop might be within the researchers' definition of appropriate. Skewing the results.

  60. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Am I missing something?


    void func()
    {
        if (AquireResource1())
        {
            if (AquireResource2())
            {
                if (AquireResource3())
                {
                    DoStuffWithResources();
                    Cleanup3();
                }
                Cleanup2();
            }
            Cleanup1();
        }
        return;
    }

  61. longjmp() by stox · · Score: 5, Funny

    is far more entertaining than a mere goto.

    --
    "To those who are overly cautious, everything is impossible. "
    1. Re:longjmp() by bobbied · · Score: 1

      Only on the right family of processors....

      --
      "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
    2. Re:longjmp() by frank_adrian314159 · · Score: 1

      A real man, I see. Not that I disagree, being a real man myself!

      --
      That is all.
    3. Re:longjmp() by andyhhp · · Score: 2

      The useful thing about longjmp() is that so few people even know about it. I find that it is a very useful question to sort the would-be "C Experts" at interview.

    4. Re:longjmp() by Anonymous Coward · · Score: 0

      Agreed: modulate the instruction set.

    5. Re:longjmp() by Anonymous Coward · · Score: 0

      Especially in your C++ code, with lots of complex objects.

  62. C++ on an MCU? by tepples · · Score: 1

    Okay, then I'd recommend C++.

    So long as your target machine is big enough to support C++'s support library. People used to joke about "Think of the elevator controllers!" as an excuse people give to hold up language design. But it's no joke anymore, as Arduino's MCU kits brought programming for a constrained machine to the masses.

    1. Re:C++ on an MCU? by ender8282 · · Score: 1

      Many of the issues that people have with using C++ on embedded systems are bunk. Here [1] is a recent discussion about C++ on embedded systems. Specifically to your point about C++ being too bloated [2] argues that the language itself isn't really.
      [1] http://app.content.ubmtechelec...
      [2] http://www.embedded.com/design...

    2. Re:C++ on an MCU? by SuricouRaven · · Score: 1

      Arduinos are for those who cannot handle PICs.

      I've used both - arduino for a password manager and a humidity-operated fan, and PIC for an electronic die and a coin crusher. A lot of things people use arduinos for, PICs can do cheaper and smaller - if you put in the coding time.

      The coin crusher as fun. If you think EMI-proofing is difficult, try making a microcontroller unit that sits next to a 200-kiloamp spark gap. The reset timer is your friend.

    3. Re:C++ on an MCU? by tepples · · Score: 1

      A lot of things people use arduinos for, PICs can do cheaper and smaller - if you put in the coding time.

      How would the C++ support library be more practical on a PIC than on an AVR? Or is it more of an ATmega vs. ATtiny thing?

    4. Re:C++ on an MCU? by SuricouRaven · · Score: 1

      Library? I did those things in asm.

    5. Re:C++ on an MCU? by SuricouRaven · · Score: 1

      The PICs, I mean. The arduinos were in good old C.

  63. Re:GOTO is a crutch for bad programmers by ultranova · · Score: 1
    void func() {
    if (AquireResource1()) {
    if (AquireResource2()) {
    if (AquireResource3()) {
    DoStuffWithResources();
    Cleanup3();
    }
    Cleanup2();
    }
    Cleanup1();
    }
    return;
    }

    Isn't this a textbook example of unwounding a stack?

    --

    Forget magic. Any technology distinguishable from divine power is insufficiently advanced.

  64. Re:GOTO is a crutch for bad programmers by jdschulteis · · Score: 1

    // I wouldn't go so far as to claim this is "better" than the goto version.
    // Especially since "goto cleanup" is a well-known idiom.
    // However, I do think this reads quite naturally.
    void func() {
        bool hasResource1, hasResource2, hasResource3;
        hasResource1 = AcquireResource1();
        if (hasResource1) {hasResource2 = AcquireResource2();}
        if (hasResource1 && hasResource2) {hasResource3 = AcquireResource3();}
        if (hasResource1 && hasResource2 && hasResource3) {
            DoStuffWithResources();
        }
        if (hasResource3) {Cleanup3();}
        if (hasResource2) {Cleanup2();}
        if (hasResource1) {Cleanup1();}
        return;
    }

  65. Re:GOTO is a crutch for bad programmers by itzly · · Score: 1

    You can't just grab a handful of lines of code and make it a separate function. A function needs to have a clear purpose, not too many arguments, and preferably not more than 1 return value.

  66. The arrow anti-pattern by tepples · · Score: 1

    Pass your post through a prettifier and see how the arrow anti-pattern becomes clear.

    1. Re:The arrow anti-pattern by Rakarra · · Score: 1

      Just wanted to thank you for that link. As a casual programmer, I'd never visited that site before, and it is quickly blowing my mind.

  67. 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;
    }

  68. Re:GOTO is a crutch for bad programmers by tepples · · Score: 1

    A switch/case statement, or function calls.

    Can you demonstrate that these improve readability of the program in all cases?

  69. Re:GOTO is a crutch for bad programmers by phantomfive · · Score: 1

    I hate that code. Precisely because it is so easy to overlook something, like you did. And even easier for a maintenance programmer coming later to overlook something.

    --
    "First they came for the slanderers and i said nothing."
  70. Re:GOTO is a crutch for bad programmers by sysrammer · · Score: 1

    Absolutely. It took me about 5 seconds to understand the snippet with the goto's. The one with brackets is just ugly, though indentation would have made it clearer and easier to match up the brackets (which of course, the OP may have done and /.'s editing tools failed to render). I imagine that a bracket mismatch could provide for some debugging hilarity, just as an errant goto. Both get the job done, though. As long as the goto logic is nice and tight, it can provide for both hard- and meat-ware efficiency.

    --
    His ignorance covered the whole earth like a blanket, and there was hardly a hole in it anywhere. - Mark Twain
  71. Don't repeat yourself by tepples · · Score: 1

    Good point. A goto statement wouldn't violate Don't repeat yourself (DRY) as much as Shakrai's suggestion.

  72. Re: GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    The army of embedded C developers standing behind you with torches and pitchforks begs to differ.

  73. There are many ways to do this by davidwr · · Score: 1

    As others have show, you can use nested conditionals, status variables, and/or other means to avoid using Goto.

    Yes, conditionals, case: statements, and similar constructs are really "goto" statements under the hood, but they are generally easier for humans to read and maintain and easier for compilers to optimize than a goto statement.

    Which of the options listed below should you use? In many cases that will depend on the "coding style" of the developer or development team rather than any minor differences in "technical merit."

    --
    Knowledge is how to play a game, intelligence is how to win, wisdom is knowing what game to play.
  74. Spaghetti calls by tepples · · Score: 1

    Actually you could split off each resource acquisition into separate function that does acquire -> check -> cleanup cycle for one resource and calls next function in chain.

    I hope you made lots of spaghetti.

    Not shorter than goto way but you're less likely to shoot yourself in the foot by messing up order of cleanups or something.

    Its lack of readability means you may end up shooting yourself in the foot when trying to understand this spaghetti seven months later when you have to make a change.

    1. Re:Spaghetti calls by loonycyborg · · Score: 1

      Because cleanup code is near acquisition code it's easier to understand than goto.

  75. It's GOTOs all the way down by Celarent+Darii · · Score: 1

    To be honest I've never understood the hate towards GOTO. In assembly language all you are doing is telling the computer where to go in order to do the next thing. In fact the program counter is a register just like any other which you modify to move to another statement, and at the very least increments by one each fetch cycle. Each and every pointer is telling the computer where to GO TO in order to find a certain variable. Each and every RETURN is an implicit goto. IF is nothing more than Branch On Equal. In fact the only thing you are doing with a computer is telling it where to take its next data and its next instruction, which at the very least is a GOTO NEXT BYTE. To fear GOTO is simply to fear the Von Neumann machine.

    Many program languages are just abstractions to try to encapsulate in some way the place or time that something is supposed to be done. But in the end, it is just a glorified GOTO statement.

    GOTOs are the only reality. If you fear GOTO, maybe there is something wrong with your philosophy, or are trying to abstract away from the problem too much.

    1. Re:It's GOTOs all the way down by Yunzil · · Score: 1

      You're kinda entirely missing the point of structured programming. In your other examples, the goto is constrained. The return statement is a goto back to the call of the function. The if statement is a goto to either the inside of the block or the end of the block.

      What Dijkstra was complaining about was unrestricted gotos. If you can goto anywhere in the code willy-nilly then it becomes much harder for someone reading your code to follow your logic. And it becomes much harder for you to follow your own logic when you inevitably have to come back to the code a year later.

    2. Re:It's GOTOs all the way down by Anonymous Coward · · Score: 0

      > In assembly language all you are doing is telling the computer where to go in order to do the next thing.

      Exactly, and that is why assembly languages (hundreds of different ones, several for each computer type) have been replaced by high level languages for most programming.

      In the early days of computers with delay line memory, the memory cycle time was so slow that several instructions could be executed in one cycle. If the instructions were laid out sequentially in memory then the CPU (mill) would have to wait for a complete memory cycle to fetch the next instruction because it would miss fetching it in the current cycle as the instruction was processed. For optimal performance the next instruction would be a few words further down memory giving time to execute the current instruction and then pick up the next with minimal delay. Each instruction contained the address of the next instruction. The data items would also be laid out in memory in specific locations based on memory cycles and instruction execution timing.

      Later machines had different timing issues and so assembly programs did no longer need to worry about instruction ordering and could use sequential layout which was much more readily understandable when reading the code.

      High level languages were designed to give as much improvement over assembly as sequential assembly had over delay line ordering in programming.

      "telling the computer where to go in order to do the next thing" is what high level languages are trying to eliminate.

  76. Re:GOTO is a crutch for bad programmers by sysrammer · · Score: 2

    I've seen 3 or 4 attempts to make the nested logic correct and/or readable. The statement with the goto's was easy to understand. Immediately. I think it proves the point that sometimes goto's have a place, and actually may be a better solution.

    --
    His ignorance covered the whole earth like a blanket, and there was hardly a hole in it anywhere. - Mark Twain
  77. Re:GOTO is a crutch for bad programmers by goose-incarnated · · Score: 1

    What horrible error-prone hard to follow code. Fair enough, it looks okay for this trivial example with only three pieces of logic in it, but real-life code has more than three pieces of logic in them. Look at this code from this library over here, line 85, function xp_new_xcfg() (unfortunately /. won't let me post the actual function code - "please use fewer junk characters").

    Using your multiple-block example this short 12 line function becomes a 30-odd line monstrosity that is harder to read, much more error-prone to write and extremely difficult to debug due to redundant lines, yet this is still a trivial, rather short function! Can you imagine the mess that would occur if you tried to convert a more substantial function with error-handling goto's into your multiple-block version?

    We were all taught the multiple-block approach to avoiding goto's when learning programming in university/school so it's not like none of us goto-using ancients ever tried it before. The problem with that approach occurs when a codebase is touched by many coders. They may not be as adept at making sure, when they modify that multiple-block version, to (for example) free the previous five pointers in the 6th failure handler "if" statement. Then we get a memory leak.

    The goto version greatly reduces the probability that someone, when adding a new line of code with error-checking into the function, will forget how many foobars were allocated prior to that line and free too few in their error-handler "if" block. All they have to do is ensure that they jump to the handler that free's all.

    --
    I'm a minority race. Save your vitriol for white people.
  78. Re:GOTO is a crutch for bad programmers by itzly · · Score: 2

    If AcquireResource1() fails, you have unitialized entries in resources[1] and resources[2].

    And this array only works if your resources all look the same.

  79. Priceless by Anonymous Coward · · Score: 0

    :)

  80. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    // Ideally, you'd use smart-pointers for the resources, but the example assumes the language doesn't provide for them. // For three resources, I'd do the following, but for much more than that, I'd start using for-loops and arrays.
    void func() {
            int acquiredResource1 = FALSE, acquiredResource2 = FALSE, acquiredResource3 = FALSE;
            acquiredResource1 = AcquireResource1();

            if (acquiredResource1)
            {
                    acquiredResource2 = AcquireResource2();
            }

            if (acquiredResource2)
            {
                    acquiredResource3 = AcquireResource3();
            } // Only need to check for acquiredResource3, but checked for all for the sake of readability
            if (acquiredResource1 && acquiredResource2 && acquiredResource3)
            {
                    DoStuffWithResources();
            }

            if (acquiredResource3)
            {
                    Cleanup3();
            }

            if (acquiredResource2)
            {
                    Cleanup2();
            }

            if (acquiredResource1)
            {
                    Cleanup1();
            }
    }

  81. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    When you have 5+ resources, then your example is not cleaner.
    Having to scroll right to see anything but white space from indenting is not clean code.

  82. Stenography when used well; steganography when not by tepples · · Score: 1

    Goto these days is a stenography tool

    Agree. It makes the code shorter so that it can be written quickly and ideally read and understood quickly as well. Eliminating some of the fluff that we discussed recently helps someone read the program by keeping more functionality on the screen at once.

    it's designed to make the code harder to read.

    Disagree, when used by a competent programmer.

  83. Re:GOTO is a crutch for bad programmers by itzly · · Score: 1

    But it doesn't work, because you didn't initialize hasResource2 and hasResource3 variables to false.

  84. Re:GOTO is a crutch for bad programmers by medv4380 · · Score: 1

    Something closer to this?
    void func () {
    for(int i=0; i if(!AquireResource(i)){
    Cleanup();
    return;
    }
    }
    DoStuff();
    Cleanup();
    return;
    }

  85. Comment removed by account_deleted · · Score: 1

    Comment removed based on user account deletion

  86. Re:GOTO is a crutch for bad programmers by jdschulteis · · Score: 1

    // You mean like this?
    // I don't mind it, but I have worked with people who would hate this style.
    void func3() {
        if (AcquireResource3()) {
            DoStuffWithResources();
            Cleanup3();
        }
    }
    void func2() {
        if (AcquireResource2()) {
            func3();
            Cleanup2();
        }
    }
    void func() {
        if (AcquireResource1()) {
            func2();
            Cleanup1();
        }
    }

  87. And aspect-oriented programming by tepples · · Score: 2, Interesting

    Return from subroutine is the same as popping a function from the stack and tail calling it. "Comefrom" is a different construct, stating that whenever some other line of the program gets executed, a particular function will get called first. Have you heard of "aspect-oriented programming"?

    1. Re:And aspect-oriented programming by Anonymous Coward · · Score: 0

      Have you heard of "aspect-oriented programming"?

      Nope. I'm a programmer, not a computer scientist dammit!

    2. Re:And aspect-oriented programming by Darinbob · · Score: 1

      I've spent 10 years in CS, and never heard of aspect-oriented programming until it appeared in a corporate setting.

    3. Re:And aspect-oriented programming by Cederic · · Score: 1

      Which is reasonable, as it's an implementation of an OO design pattern - so firmly in the software engineering camp, rather than the computer science one.

      As with all patterns, it appears to be overused and used inappropriately. But maybe I'm just a grumpy old man.

    4. Re:And aspect-oriented programming by KlomDark · · Score: 1

      Aspect oriented? Oh yay, what have the hipster programmers reinvented this time? Yawn...

    5. Re: And aspect-oriented programming by Anonymous Coward · · Score: 0

      Is it goat too or goat to?

    6. Re:And aspect-oriented programming by Anonymous Coward · · Score: 0

      AOP is bullshit designed to get around the bullshit and totally-misses-the-point OO system that Java has.

    7. Re: And aspect-oriented programming by Anonymous Coward · · Score: 0

      Neither. It's goat se.

  88. Re:GOTO is a crutch for bad programmers by MagickalMyst · · Score: 0

    Why? My point has been made.

    --
    Political correctness is really just herd psychology pushed by insecure people who desperately seek social conformity.
  89. Goto, like Earth by kcwhitta · · Score: 1

    Mostly Harmless.

  90. Re:GOTO is a crutch for bad programmers by Tailhook · · Score: 1

    There are serious bugs in your attempt.

    Both hasResource3 and hasResource2 are tested in the cleanup portion without having been initialized when at least one of of AcquireResource1() or AquireResource2() fails; they'll have some undefined value from the stack and Cleanup3/2() will be called inappropriately. This is true in both C, which has no 'bool' or C++, which does have bool, but won't automatically initialize it when auto.

    The goto version does not involve creating the bool state variables and so avoids this subtlety. That makes the goto version inherently better, in my opinion.

    --
    Maw! Fire up the karma burner!
  91. Re:GOTO is a crutch for bad programmers by bobbied · · Score: 1

    Man, you just blew another coding rule of thumb....

    There should be only ONE return statement in a function, especially when said function doesn't have a return value...Exceptions to this should be CLEARLY commented to not confuse those who maintain your code.

    --
    "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
  92. Re:GOTO is a crutch for bad programmers by tepples · · Score: 1

    What would you propose as a better alternative

    A switch/case statement, or function calls.

    Can you demonstrate that these improve readability of the program in all cases?

    Why? My point has been made.

    Because I disagree with you that your "point has been made" until you have shown how it is "a better alternative".

  93. Re:GOTO is a crutch for bad programmers by Tailhook · · Score: 1

    Am I missing something?

    Taste.

    --
    Maw! Fire up the karma burner!
  94. goto fail; by janeuner · · Score: 1

    Did we already forget?
    https://www.imperialviolet.org...

    int err;
    if ((err = PrepareHash(x,n)) != 0)
        goto fail;
        goto fail;
    if ((err = CalculateHash(x,n)) != 0)
        goto fail;
    return CompleteHashx,n);

    fail:
    return err;

  95. Re:if (i_use_GOTOs) { goto_school(); } by Anonymous Coward · · Score: 0

    "GOTO" should never have been allowed in C.

    Yes, it should. But that doesn't mean you should use it.

  96. Re:GOTO is a crutch for bad programmers by MagickalMyst · · Score: 1

    You obviously have much more time on your hands.

    Do you realize how absolutely ludicrous that is? Demonstrating readability in "ALL" cases?

    Sorry, but I have better things to do than entertain naysayers.

    --
    Political correctness is really just herd psychology pushed by insecure people who desperately seek social conformity.
  97. Don't forget to thank Dijkstra for that by cloud.pt · · Score: 1

    From a very superficial analysis, I'd say the fact that Dijkstra, among others, mentioning it back in the day really influenced the practice nowadays. That is yet another consequence of the enlightened influence the most knowledgeable imprint in society over the ages. The study is surely good science. Nonetheless, good science is only as good as the context it is applied, so the conclusions, even though interesting, must be made and taken with a grain of salt. This is because pretty much like testing human aggressiveness during primitive periods and testing it now would obviously provide the most disparate results in multiple orders of magnitude, and the same would have happened with this GOTO theme if there was this parallel universe we could compare - one where Dijkstra and co. hadn't chimed in about the subject, and nobody else stepped in to replace them. The greatest conclusion I personally take here is that such a large amount of code was influenced with the good practice evangelized by Dijkstra, and the pondered decisions that were made about the subject. Pretty much the same reason why IT is paying more and more attention to things like QA, agile, documentation, process, workflow and integration - we get these enlightened, experienced entities (individuals and companies alike) showing us just how important they are, and we apply those concepts with assurance that they will lead to better results.

  98. Re:why? What about Partial Pendants by Anonymous Coward · · Score: 0

    You seem to classify people into two categories Pendant and not Pendant. I am sure many people are partial pendants.

  99. Re:Equally stupid dogma and MISRA by grimmjeeper · · Score: 1

    I had to write code that used MISRA standards and even had the standards worked into compiler to generate errors so you couldn't just ignore the stupid.

    It took me about 5 minutes reading through the MISRA standards to figure out that it was written by a committee of bureaucrats who don't actually know how to write software. Sure, there were some good things in the standard to improve readability and things like always using braces with every conditional so you can avoid problems like the Apple "goto fail" screw up. But several standards showed a complete lack of understanding about the definition of the C language. According to one of their rules, you couldn't test for a null pointer and then use the pointer in the same statement. The most notable example I can think of was the very common place ( && ) construct. Even though the && operator is a shortcut operator that absolutely checks the left hand side and kicks out if it is false (i.e. when the pointer is null), the brain trust at MISRA wouldn't let you do that. The language is defined to work correctly and you can't call yourself a C compiler if you break functionality like that. But no, MISRA standards won't let you do that because it "might" cause you to dereference a null pointer. It's a perfect example of good ideas being taken way too far and then turned into rigid dogma run amok.

    Coding standards are good. Encouraging (but not requiring) people to not use GOTO unless they really have to is a "good thing". When you can't use C++ but you've designed your system to mimic destructor behavior and "exception" like error handling (i.e. to mimic RAII behavior), there are times when it's hard to do it any other way. The C language just doesn't give you the tools you need to implement OOD any other way.

    I've been programming for over 35 years now and I remember the disgusting mess that you found yourself in with GOTOs sending yourself all over hell and gone. So I understand what Dijkstra was warning us against. And he has a point. You don't want to use GOTO as your only form of flow control. It quickly devolves into an unreadable mess. But pretty much every language these days has conditionals and loops to keep programs well organized and everyone knows how to use them properly. The GOTO is left to times when it's really necessary, as it should be. Because sometimes it really is necessary.

  100. You shoulda seen programs before Djikstra! by mileshigh · · Score: 5, Informative

    In the 60's and much of the 70's, most people wrote in high-level languages as if they were coding assembler. Goto's all over the place. Not that they had a choice -- for example, control flow in Fortran IV, the most-used high-level language of the time, featured IF, DO (a crude version of the modern FOR -- not do), GOTO, CALL, RETURN. No else, while, do/while, no modern-style for, case, etc. AND, get this: NO BLOCKS; the IF statement controlled only a *single* statement, so that meant you often *had* to say IF (...) GOTO xxx. Just like assembler. It was awful! There were other less-popular but more-evolved languages, but unstructured practices were very often carried over to those as well. GOTOs were just how most programmers thought.

    That's the backdrop for Djikstra's condemnation of GOTO. Certainly, the then-current mass use of GOTOs was a very bad thing since it completely obscured program logic. If you read the original article, he's not so much condemning GOTO as he's arguing for structured programming.

    Consider GOTO Considered Harmful as a successful wake-up call. By keeping his message black/white, i.e. GOTO is bad, he gave his message punch and made it much talked-about. People started to think in a more structured manner (though at first we thought the "structured crowd" were a bunch of weenies), and started to demand better control-flow features. Pretty soon, structured control-flow was de rigeur in any new or revised language. Fortran even got IF/END IF in Fortran 77!

    People nowadays have hardened the anti-GOTO bias into gospel. At the time, the response was more nuanced, more in line with the spirit of what Djikstra was saying. For example, in 1974 even Niklaus Wirth's new PASCAL (a principled, hard-line structured language if there ever was one) included the goto statement with the warning in the User Manual and Report that "the goto statement should be reserved for unusual or uncommon situations where the natural structure of an algorithm has to be broken." If anybody was going to out-and-out outlaw goto, Wirth would have been the guy.

    1. Re:You shoulda seen programs before Djikstra! by Richy_T · · Score: 1

      This is the summary I was looking for. Good work.

    2. Re:You shoulda seen programs before Djikstra! by spauldo · · Score: 1

      I can second the whole "thinking in gotos" thing.

      I learned BASIC on various micros in the 80s (mostly C64 and Atari 800) and it was pretty much the same thing. The most "structured" you got there was using the GOSUB statement.

      Then I sat down in front of a PC and tried writing a program in QBASIC - and some bastard stole my line numbers! How was I to structure my code? What's all this looping crap? Learning Pascal in high school was even more of a culture shock - I kept looking across the room at the rows of Apple ][e machines and missing my GOTOs.

      Oh well, I'm all cured of that now. I'm just glad I wasn't started on COBOL. The damage may never have been undone.

      --
      Those who can't do, teach. Those who can't teach either, do tech support.
  101. Re:GOTO is a crutch for bad programmers by Agent0013 · · Score: 1

    Sure indentation can help. But at the last place I worked they would have so many nested if statements that it would indent all the way across the screen. It was quite hard to keep track of which set of braces you were inside of. I don't know if goto's would have helped in their case, but too many nested groups definitely hurts readability.

    --

    -- ssoorrrryy,, dduupplleexx sswwiittcchh oonn.. -Quote found on actual fortune cookie.
  102. Re:GOTO is a crutch for bad programmers by SuricouRaven · · Score: 1

    If you are three levels of brackets deep before your important code even starts, you're doing it wrong.

    I think my personal record is 27 layers of curve-and-angle brackets in, while doing some intricate bitmap manipulation - but that's largely because I like to make sure all my arithmatic is unambiguous even for those who can't follow the order of operations. I often end up with something like total+=bitmap[(x+offx+(width*(y+yoff)))*3]+bitmap[((x+offx+(width*(y+yoff)))*3)+1]+bitmap[((x+offx+(width*(y+yoff)))*3)+2]. It's pretty ugly.

  103. Re:GOTO is a crutch for bad programmers by pz · · Score: 1

    You could do the following, and with a little non-standard indenting, it's rather more elegant, I think.


    void func() {
          if (AcquireResource1()) {
          if (AcquireResource2()) {
          if (AcquireResource3()) {
                DoStuffWithResources();
                Cleanup3;
          }
                Cleanup2;
          }
                Cleanup1;
          }
    }

    --

    Put my fist through my alarm clock with its ding-dong death inside my ear. - The Blackjacks.
  104. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    void func() {
    bool haveResource1 = AquireResource1();
    bool haveResource2 = AquireResource2();
    bool haveResource3 = AquireResource3();

    DoStuffWithResources();

    if (haveResource3)
        Cleanup3();
    if (haveResource2)
        Cleanup2();
    if (haveResource1)
        Cleanup1();
    }

  105. Re:GOTO is a crutch for bad programmers by frank_adrian314159 · · Score: 1

    Well, to me, this is even more clear:


    (defun func ()
          (with-resource1 (x (acquire-resource1))
                (with-resource2 (y (acquire-resource2))
                      (with-resource3 (z (acquire-resource3)) ;;; Do stuff with the resources
    ))))

    with the "with-" macros handling any local bindings and/or cleanup for the resource. It's a well-known pattern.

    --
    That is all.
  106. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    I'm a fan of early returns.


    void func() {

          if (!AquireResource1()){
                  return;
          }

          if (!AquireResource2()){
                Cleanup1();
                return;
          }

          if (!AquireResource3()){
                Cleanup2();
                Cleanup1();
                return;
          }

          DoStuffWithResources();

          Cleanup3();
          Cleanup2();
          Cleanup1();
          return;
    }

  107. So you avoided indenting conditional code by perpenso · · Score: 1

    if (!v)
    goto out;
    more work ...
    out:

    It makes it so much cleaner and easier to read.

    What problem did you solve, indenting a conditional block of code?

    How is it more readable to mask / hide the fact that a block of code is conditional?

    1. Re:So you avoided indenting conditional code by Richy_T · · Score: 1

      Good point.

    2. Re: So you avoided indenting conditional code by Anonymous Coward · · Score: 0

      here we go again :/.

  108. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0
  109. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    No GOTO? No problem!

    void func() {
        if (!AquireResource1()) fail1: {}
        if (!AquireResource2()) fail2: {}
        if (!AquireResource3()) fail3: {}

        DoStuffWithResources();

        Cleanup3();
        comefrom fail3;
        Cleanup2();
        comefrom fail2;
        Cleanup1();
        comefrom fail1;
        return;
    }
    Wait, C doesn't have COME FROM?! crap. Time to alert the C standards body!

  110. Re:GOTO is a crutch for bad programmers by goose-incarnated · · Score: 1

    http://pastebin.com/wMeeMKVb

    Just sayin'

    Thanks for the attempt - it illustrates the problem quite nicely. If any of the xstr_dup calls fail you leak memory. The original one I linked to will not leak memory no matter which line fails.

    --
    I'm a minority race. Save your vitriol for white people.
  111. Re:GOTO is a crutch for bad programmers by Megane · · Score: 1

    int i;
    bool ok = true;
    for (i = 0; ok && i < 3; i++) {
    ; switch (i) {
    ; ; case 0: if (!AcquireResource1()) ok = false; break;
    ; ; case 1: if (AcquireResource2()) ok = false; break;
    ; ; case 2: if (AcquireResource3()) ok = false; break;
    ; }
    ; if (!ok) break;
    }
    switch(i) {
    ; case 3: Cleanup3();
    ; case 2: Cleanup2();
    ; case 1: Cleanup1();
    }

    Why yes, I read thedailywtf.com, why do you ask?

    --
    #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
  112. Re:GOTO is a crutch for bad programmers by Megane · · Score: 1

    minor change:

    case 2: if (AcquireResource3()) ok = false; else DoStuffWithResources(); break;

    --
    #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
  113. Re:GOTO is a crutch for bad programmers by Megane · · Score: 1

    It's called the DRY principle, as in Don't Repeat Yourself. Any time you do the same sequence of stuff in multiple places, when that sequence needs to change, the chance of missing one is increased.

    --
    #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
  114. Re:if (i_use_GOTOs) { goto_school(); } by david_thornley · · Score: 1

    C was a system implementation language, which meant that it needed very basic constructs. "goto" is one, and the ability to read and write to specific pieces of memory is another.

    --
    "When you have eliminated the unacceptable, whatever is left, however improbable, must be the truthiness" - Holmes
  115. Re:GOTO is a crutch for bad programmers by Megane · · Score: 1

    There should be only ONE return statement in a function

    Um, yeah, I'm gonna have to put up a [CITATION NEEDED] here. Sure, that's a thing, but so is Systems Hungarian Notation.

    --
    #naabhaprzrag, #sverubfr-000, #agi-fcbafberq, negvpyr[pynff*=' negvpyr-ary-'] { qvfcynl: abar !vzcbegnag; }
  116. goto exit by seepho · · Score: 1

    Is pretty useful.

  117. It was a terrible example of went to use a goto by perpenso · · Score: 1

    No, he's objecting to the example offered as an appropriate use of goto. It wasn't an appropriate use. It fails at the stated goal, making the code more readable. It makes it less readable by avoiding the indentation of conditional code.

    If there had been a different example with nested code at various levels bailing out with goto's then maybe it would have been appropriately used, not necessarily but maybe. However as offered the example was a good example of when *not* to use a goto.

    1. Re:It was a terrible example of went to use a goto by vilanye · · Score: 1

      > I say "please don't use goto" and instead have a "cleanup_lock" function
      > and add that before all the return statements.. It should not be a
      > burden. Yes, it's asking the developer to work a little harder, but the
      > end result is better code.

      No, it is gross and it bloats the kernel. It inlines a bunch of junk
      for N error paths, as opposed to having the exit code once at the end.
      Cache footprint is key and you just killed it.

      Nor is it easier to read.

      As a final argument, it does not let us cleanly do the usual stack-esque
      wind and unwind, i.e.

              do A
              if (error)
                      goto out_a;
              do B
              if (error)
                      goto out_b;
              do C
              if (error)
                      goto out_c;
              goto out;
              out_c:
              undo C
              out_b:
              undo B:
              out_a:
              undo A
              out:
              return ret;

      Now stop this.

              Robert Love

      http://koblents.com/Ches/Links...

    2. Re:It was a terrible example of went to use a goto by perpenso · · Score: 1

      Note that Torvalds concedes that the specific code example being complained about does not benefit by the use of goto.

      Also not brought up in that discussions is that where to draw the line between goto and nesting depends on the amount of nesting and the length of the code in question, not nesting alone. People using goto in shorter simpler code are making the code less readable.

      Now Love's example is a great one because of the falling through from one undo to another. Because the bailout applies to all nesting levels so far not just the current level. That would be awkward in purely structured code. However if the undo were constrained to only the err'ing level, if there had been a goto out after undo C and undo B then structured if/else would have been more readable. But as is with multiple levels of undo it is s very appropriate use of goto.

      Unfortunately much use of goto is done when the code is simple and short, unlike Love's example.

  118. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    void func() {

    int bail = 3;
    if (!AquireResource1()) bail = 0;
    if (!AquireResource2()) bail = 1;
    if (!AquireResource3()) bail = 2;

    DoThings();

    switch(bail) {
        case 3: cleanup3();
        case 2: cleanup2();
        case 1: cleanup1();
    }

    return;
    }

    But of course, taking advantage of switch fallthrough is nothing but a translucent fig leaf over a bunch of gotos. I.e., very useful to have in mind if you're dealing with a Religious Fundamentalist who hates goto No Matter What.

    There are times you have to use goto. I once needed unknown-depth recursion in CUDA but __device__ functions are verboten from calling themselves (nvcc needs to know stack size at compile time so it knows how many resources to allocate at launch). But I needed unknown-depth recursion (even if I had a good idea what the max would be) so I #defined a MAX_DEPTH and put a variable called "stack" to track my paths through the octree and I used GOTO to loop over a section of code an unknown number of times. The code had to traverse an octree with up to ~10s of millions of elements at the final level, determining a union of subsets of each level which exactly covered the 3D space it represented to perform a weighted sum over them (it computed the integral solution of the Poisson equation at an arbitrary point).

    I won't pretend it was pretty but oh lordie lord did it ever zip along... Surprisingly the process is amenable enough to Matlab's vector/set notation that I got the .m version to run fully half as fast as the compiled .c version, which itself was about 1/10 as fast as the .cu version.

  119. Re:GOTO is a crutch for bad programmers by ShanghaiBill · · Score: 1

    If you are three levels of brackets deep before your important code even starts, you're doing it wrong.

    Perhaps. But the real problem is bad design of the functions being called. The code should look like this:

    void func() {
        int resources = R1 | R2 | R3;
        if (acquireResources(resources)) {
            doStuffWithResources();
            releaseResources(resources);
        }
    }

    This way the error handling, and sequencing of acquiring and releasing, are completely separated from your code flow, and buried in a subroutine that can be reused whenever needed. You may be able to come up with a contrived example where "goto" seems appropriate, but that is usually a symptom of bad design on another level.

  120. Re:GOTO is a crutch for bad programmers by Wrath0fb0b · · Score: 1

    Use a single generic cleanup that only cleans up what it has to clean up. That way you don't have a difference between the regular code path and the exception path. Also keep track explicitly on what you have allocated and what you haven't.


    int func(void)
    {
        int something = E_NORESOURCES;
        ResourceHandle handle1 = NULL;
        ResourceHandle handle2 = NULL;
        ResourceHandle handle3 = NULL;

        handle1 = GetResource1();
        if ( ! handle1 ) goto out;

        handle2 = GetResource2();
        if ( ! handle2 ) goto out;

        handle3 = GetResource3();
        if ( ! handle3 ) goto out;

        something = DoSomething(handle1, handle2, handle3);

    out:
        if ( handle1 ) Release(handle1);
        if ( handle2 ) Release(handle2);
        if ( handle3 ) Release(handle3);

        return something;
    }

  121. Re:GOTO is a crutch for bad programmers by BirdBrained · · Score: 1

    RAII and modern C++ get rid of this error-prone coding style. The shared_ptr and unique_ptr template classes, with custom deleters if necessary, can remove all of these contortions and prevent someone from adding a return in the middle of the method that would lead to resource leaks..

  122. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    OK so I refactored again and it's getting messy :)

    http://pastebin.com/geq6C1rg

    I DO see the utility of GOTO statements - I grew up with 10 Print "Hello", 20 Goto 10, so it always has a place in my heart lol.

    Just trying to play devils advocate here, and learning some along the way. Just a casual programmer here.

  123. Something python has taught me... by FryingLizard · · Score: 1

    ...is that consistent indentation makes code vastly easier to read and much harder for bugs to hide in; I imagine pretty much everyone nowadays uses auto-indentation when writing C code, which if course is curly-bracket based. If you use "GOTO" suddenly your indentation doesn't match your program flow; it's asking for trouble.
    For the same reason I try to avoid doing a "RETURN" in the middle of a function where reasonable (if I need to bail due to an error etc I try to do it right at the start of a function before any of the meat)
    That just leaves "BREAK" as a program-flow-modifier and I can live with that just fine.
    I don't think I've _ever_ used GOTO in several decades of programming C.

    --
    [FrLz]
    1. Re:Something python has taught me... by shutdown+-p+now · · Score: 1

      I don't think I've _ever_ used GOTO in several decades of programming C.

      Have you ever done error handling when writing C? What do you normally do when you have, say, two socket descriptors opened, and then three function calls, each of which may fail with an error and require you to bail out, while closing both of those sockets?

  124. Banging out initial code quickly ... by perpenso · · Score: 1

    The academics are always on a quest for purity, people who work for a living want to get things done as cleanly and quickly as possible.

    Banging out code quickly during initial development is rarely getting things done quickly in the long run. One must also consider maintenance and future updates and enhancement, often made by someone other than the initial developer, which is where time gets lost due to mistakes during initial development. Many have good intentions of going back and cleaning up initial code but actually getting a chance to do so is not as common as many wish.

    The general idea is that misuse of goto leads to buggier code, and that bugs are less expensive the earlier they are found, and ideally avoided in the fist place by good coding practices. So banging out code quickly can be counterproductive.

    As for cleanly coded, what is cleaner and more readable about masking that fact that a block of code is conditional by avoiding indentation, which is all that the offered goto example is doing. Perhaps if the example had bailouts from several levels of nesting, but even in such situations goto is not necessarily the best way to go.

    1. Re: Banging out initial code quickly ... by Anonymous Coward · · Score: 0

      you keep bringing up indentation and nobody is biting. maybe you are the only one with this indentation problem. this is the 5th time you posted about indentations using goto. someone debunked you higher up and you still keep spouting it. give it up bro.

  125. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    error1 |= AquireResource1();
    error2 |= AquireResource2();
    error3 |= AquireResource3();

    if((error1 == FALSE)
    &&(error2 == FALSE)
    &&(error3 == FALSE))
    {
    DoStuffWithResources()
    }
    else
    {
    if(error3 != FALSE) {Cleanup3;}
    if(error2 != FALSE) {Cleanup2;}
    if(error1 != FALSE) {Cleanup1;}
    }

    And this isn't even the best alternative option to your goto, but your example was more difficult to read, and you are assuming that the labels will stand out.

    I also don't see why you would just have one cleanup call. If you were THAT stressed on runtime, then perhaps goto would be better, but it also depends how the compiler interprets this anyways.

  126. Re:GOTO is a crutch for bad programmers by goose-incarnated · · Score: 1

    Yeah, now imagine how messy it gets when you have to free each of the results from xstr_dup individually and not miss any - turn this function into one without goto's.

    It gets worse actually - this example was structured purely to make error handling easier. Some error handlers call functions to free resources that can't take NULL (fclose, for example). This trivial function uses free(), which can take NULL so we don't have to check if each variable is non-NULL before we free it. If those were file handles we'd have to check them for less than zero before we can fclose them.

    --
    I'm a minority race. Save your vitriol for white people.
  127. 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!
    1. Re:I agree by CastrTroy · · Score: 1
      It's similar to Djikstra's quote about Basic.

      It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.

      This was at a time when BASIC didn't even support subroutines or many things, yet people still use it as a reason to be against things like VB.Net, even though it's just as capable as C#.

      --

      Anthropic principle: We see the universe the way it is because if it were different we would not be here to see it.
    2. Re: I agree by Anonymous Coward · · Score: 0

      VB.Net is as capable as C# now. While 3 and 3.5 were the newest version of .Net it lagged behind a lot in features.

      Oh, and the delegate syntax is still ugly enough to make me hate VB

    3. Re:I agree by DNS-and-BIND · · Score: 1

      Well, it worked, didn't it? He made 45 years of programmers afraid to use a GOTO unless in dire need. It's as valid today as when he spoke it.

      --
      Shutting down free speech with violence isn't fighting fascism. It IS fascism!
    4. Re:I agree by Anonymous Coward · · Score: 0

      Exactly, I've seen scientists (astronomers to be precise) religiously believing in Djikstra's commandment, replicate hundreds of lines of code to avoid a single goto. It obviously becomes much more difficult to maintain. Note that it was Fortran 77, on a VAX if I remember correctly, so you had the basic counted and while loops available (but no equivalent of break or continue in C as far as I remember).
      Like all programming constructs, goto is a tool, if it is present even in languages like Ada, it is because the language designers recognized that there are cases where it is the lesser evil, mostly for handling corner cases which include errors, early exit from deeply nested constructs, or infrequent conditions which need cleanup.
      Note that the code in question could probably not even have been written cleanly without goto in Ada (in which you can at least cleanly exit nested loops, something sorely missing in C).
      Now don't get me started on computed and assigned gotos in Fortran, I've seen Fortran ode use assigned goto to emulate call to subroutines within a single function, this avoided using common blocks or passing a very long list of arguments, but this made the code impossible to follow. This would have been cleaner in Ada with nested procedures, or even in PL/1 or Pascal. C does not have nested procedures, but you can always pass a pointer to a structure which contains the only variables which are shared between the caller and the callee, so that's fine. It is even perhaps better, because this limits the set of variables of the caller that you can modify, which in the end documents which variables are used and which ones are private to the caller, and may also help the compiler, but it becomes messy when there are several functions which need a different subset of the caller's variables.

    5. Re:I agree by NickFortune · · Score: 1

      Well, it worked, didn't it? He made 45 years of programmers afraid to use a GOTO unless in dire need.

      Well, he definitely got the point across. And it was a point that needed making, certainly.

      It's as valid today as when he spoke it.

      Is it? The problem was never with the goto statement per se. The problem was huge monolithic code blocks with flow control effectively obfuscated by arbitrary gotos.

      The thing is, this was before the days of structured programming, let alone OO. One goto in a 20 line function is not going to bring about a return to those evils. And even if we all decided tomorrow that gotos were all right after all, it's unlikely that we'd all return to writing 10,000 line subroutines controlled only by gotos.

      On the other hand, it's perfectly possible to write spaghetti code without a single goto. You can use exceptions, delegates, lambdas and inheritance to make a far more confusing mess than Djikstra ever dreamed possible.

      Overall, I think it was a valid point and well made, but I honestly question its relevance in the context of modern languages and practices.

      --
      Don't let THEM immanentize the Eschaton!
    6. Re:I agree by kmoser · · Score: 1

      I call BS on Djikstra. I grew up learning to program in those bad ol' days of BASIC (and let's not forget assembler). A few years later when I "graduated" to function-oriented languages like Pascal and C, I left BASIC behind forever, along with the dreaded GOTO. That was decades ago and I don't think I've used one GOTO-like construct since then (well, not counting HTTP redirect headers!).

    7. Re:I agree by Anonymous Coward · · Score: 0

      Right, because everybody loves a language that has a fucking separate "integer division" operator and therefore throws tantrums when you try to write bog-standard divide-and-process-modulus calculations on time or currency fields. VB (.Net or otherwise) is NOT a good language.

  128. It is not the GOTO that is the problem. by Anonymous Coward · · Score: 0

    It is not the GOTO that is the problem, it is the label that is the target.

    When examining a piece of code (not written by you) and seeing a goto it is quite obvious what will happen at that point. The flow of logic can be easily worked out. If, however, you are looking at some code and you see a label then the flow of logic can only be determined by examining the whole of the scope in which that label appears.

    This reduces the localization necessary to identify how the program works.

    The original programmer is unlikely to notice that this is a problem because in writing the code they understood what was happening and thus that there was a more limited scope.

    Writing programs that the _next_ programmer can understand is an art that is seldom practised, especially among coders that think that goto is OK to use.

    1. Re:It is not the GOTO that is the problem. by Anonymous Coward · · Score: 0

      I disagree. Just take a look at the linux kernel: goto is used A LOT, and exclusively for cleanup, and that's how most people use it these days. The labels are easily located at the bottom of the function and when you see "goto err_out" you automatically know where to look for it anyway. If however someone decides to do a loop with a goto then yes, he's a moron and should be punished. But that's not what I've seen in the wild.

  129. Re:Equally stupid dogma and MISRA by grimmjeeper · · Score: 1

    So much for proofreading. The ( && ) construct got cut out by the HTML parser. I'll retype it. It should read "the very common place ((NULL != ptr) && (-insert some user of the pointer here-)).

  130. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0
  131. Goto's are the only sane way to handle errors in C by jschultz410 · · Score: 1

    Explicit stack unwinding in an error condition, checking exit point invariants and a single exit point are why most C functions should use goto's in the real world.

    typedef struct
    {
        V v;
        W w;
        X x;
        Y y;
        Z z;

    } Resources;

    int Resources_init(Resources *r)
    {
        int ret;

        if ((ret = V_init(&r->v)))
            goto FAIL;

        if ((ret = W_init(&r->w)))
            goto FAIL_V;

        if ((ret = X_init(&r->x)))
            goto FAIL_W;

        if ((ret = Y_init(&r->y)))
            goto FAIL_X;

        if ((ret = Z_init(&r->z)))
            goto FAIL_Y;

        assert(0 == ret);
        goto END;

    /* error handling and return */

    FAIL_Y:
        Y_fini(&r->y);

    FAIL_X:
        X_fini(&r->x);

    FAIL_W:
        W_fini(&r->w):

    FAIL_V:
        V_fini(&r->v);

    FAIL:
        assert(0 != ret);

    END:
        return ret;
    }

    Try to accomplish similar logic with nested if's and it will be garbage code. C++ has exceptions, constructors and destructors while C does not. You have to hand code the same logic unfortunately and check and handle every return for potential failure.

  132. Re:if (i_use_GOTOs) { goto_school(); } by jschultz410 · · Score: 1

    Please explain how else to handle error conditions sanely in C? For example, how do you cleanly implement a function that needs to acquire N resources where any one of the acquisitions can fail and on failure you need to clean up after yourself?

  133. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    When you have 5+ resources, then your example is not cleaner. Having to scroll right to see anything but white space from indenting is not clean code.

    Are you using a 40 column Apple II?

  134. Re:GOTO is a crutch for bad programmers by itzly · · Score: 1

    Without indent, it becomes really hard to determine which { goes with }, especially if you make the code a bit longer. And with indent, it quickly becomes too deep.

  135. A pretty pointless study I would say by angel'o'sphere · · Score: 1

    When Djikstra wrote his article, languages like C and Pascal with while() and do {} while() loops did not exist.
    Gotos where very famous in Fortran and what ever was used at that time.
    If a modern developer, regardles how 'young', abused gotoes in C or similar languages I would wonder why. It would be a clear sign he did not grasp the loop or conditional constructs properly. Note 'abused' not 'used'. However I'm not aware I ever needed a goto in the last 30 years, after I was done with Basic.

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    1. Re:A pretty pointless study I would say by shutdown+-p+now · · Score: 1

      When Djikstra wrote his article, languages like C and Pascal with while() and do {} while() loops did not exist.

      If you think that while-loops were popularized by C or Pascal, I have a surprise for you. Note, this is from 1960, but the first version of the language already had in in 1958!

      Heck, when Dijkstra wrote it, there was already Simula-67 out there, which had classes and objects, virtual functions with overriding, and access modifiers (on top of everything Algol had). If you ever wondered where "virtual" and "new" in C++ came from by the way, that's its origin.

      And then there was Algol 68, with structs and unions (again, that's where C stole that stuff), function pointers, and a lot of other gimmicky stuff. Also, "void".

      Most of the things in programming are much older than people assume these days.

    2. Re:A pretty pointless study I would say by angel'o'sphere · · Score: 1

      Ah, my bad. I thought Djikstras article was from the 1960.

      Anyway, my point is: at that time people relied on gotos as the languages in use had not much more to offer.

      In our day C (or any other language) we have plenty of control structures and so it is no wonder that gotos are only used sparingly and usually more or less in a justifiable manner.

      So making a new study that concludes: "oh goto's are not that abused at all", is rather pointless imho.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    3. Re:A pretty pointless study I would say by shutdown+-p+now · · Score: 1

      Dijkstra wrote it in 1968. At that time, there was still an active debate over whether structured programming (i.e. loops and functions) was genuinely useful, or a fad that made compilers more complicated than they need to be, and generate suboptimal code. Dijkstra's letter was basically an argument in favor of the former camp, which has ultimately won by 1970s. So yes, it's not really a meaningless comparison given today's state of affairs.

    4. Re:A pretty pointless study I would say by angel'o'sphere · · Score: 1

      Funny that Simula looks half like Ada :D never really looked at how its source code looks. Thanx for the inspiration.

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
    5. Re:A pretty pointless study I would say by shutdown+-p+now · · Score: 1

      It shouldn't really be surprising - Ada is clearly derived from Pascal, and Pascal is both a simplification and an extension of Algol-60 (with Algol-W as the intermediate step) - removing exotic stuff like label variables and call by name, but extending the type system significantly (with records and pointers, most importantly). Simula is also a direct derivative of Algol-60 - if I remember correctly, it's actually a strict superset, and retains the entire Algol-60 language as a core, but then adds OOP constructs on top. So large parts of the keyword vocabulary are the same, for example.

      Algol-68 is another interesting one. Doesn't really have much with common with Algol-60, but you'll find a lot of precursors of C syntax and semantics in it. Pretty much all C built-in types come from it, including things like "short int" and "long long int", for example, as does the general "type name = initializer" syntax for variable declarations. I've already mentioned structs and unions. OTOH, it still uses keywords rather than curly braces to delimit blocks, so it looks like some strange cross between C and Pascal from a modern perspective.

    6. Re:A pretty pointless study I would say by angel'o'sphere · · Score: 1

      Interesting book!

      Funny that they had the 'made easy' (lucky it is not a 'in 21 days' or 'for dummies') books already at that time.

      Actually, it is not that old. I wonder if it was aimed towards the upcoming y2k reengineering? I only saw like 200k lines of Algol at that time. The owner believed it was PL1, sigh ...

      --
      Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  136. Dijkstra = World's WORST programmer by Anonymous Coward · · Score: 0

    No Alpha ever listened to a word uttered by this self-promoting moron. Anyone who ever went to university to do any course connected with computers came across a lame-dog 'teacher' like Dijkstra. A puffed-up idiot so full of himself, he never noticed his skillset was atrocious, his inherent abilities almost non-existent (save for self-promotion and academic ladder-climbing), and his general knowledge of computing n years out-of-date where n = idiot's age - 20

    It is the dribbling betas who chant "Duh- only bad programmers use GOTO, duh", just as they are trained- and actually for dribbling Betas, the advice is undoubtedly good.

    Most programmers are BAD programmers, just as most people in any field of skill are BAD at that skill. But these bad programmers are the majority of working programmers. Their heroes are NEVER people like Knuth (an alpha), but people like Dijkstra who spends his life taking pot shots at programmers infinitely more talented the he. The old 'chip on the shoulder' psychology.

    However, in a world of dumbed down shit like Win8/Win 10 'Metro', Dijkstra should feel in his element. This is the age of the rising moron, where functionality and sophistication are looked down on. Where everyone must use 'plastic scissors' because 'real' scissors might end up with someone cut or stabbed. GOTO, in a language, is like the point or shearing edge of metal scissors. A 'GOTO-free' language is the plastic scissors of programming.

  137. How many kilobytes for exception lib? by tepples · · Score: 1

    C++ exceptions are commonly trotted out as the replacement for C's goto cleanup statement, and for desktop userspace, I might agree. Page 2 of your second link mentioned that exception support has a cost but didn't quantify it. Instead, it said "buy our e-book for $24.95". So all I have to go on is a personal anecdote, namely that the last time I tried adding exceptions to a C++ project that hadn't previously used them, it added 64K of code to the executable.

  138. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    That idiom doesn't scale well. Here's a scalable alternative in Lua:

    function Cleanup1() ....
    function Cleanup2() ....
    function Cleanup3() ....

    function func()
            cleanup = {} --stores all the cleanup functions to run
            repeat
                    if not AquireResource1() then break end
                    table.insert(cleanup, Cleanup1)
                    if not AquireResource2() then break end
                    table.insert(cleanup, Cleanup2)
                    if not AquireResource3() then break end
                    table.insert(cleanup, Cleanup3)

                    DoStuffWithResources()
            until true --never loops

            --loops backwards calling each registered cleanup function
            for i=#cleanup,1,-1 do
                    cleanup[i]()
            end
    end

    It is more lines of code, but it's far less brittle. You can mess around with the resource acquisitions without worrying about keeping the cleanup code in sync. If for some reason you have a lot of resources/requirements, you can toss those functions into a table (paired with their cleanup function) and convert all those if nots into a loop.

  139. 99% of cases: by chopper749 · · Score: 1

    while(1){printf("FART\n");}

  140. Re:GOTO is a crutch for bad programmers by Durrik · · Score: 1

    if you're doing an init function you should match it with a deinit function.

    So:

    int initFunc() {
    if (!AquireResource1()) return deinitFunc(TERM_1);
    if (!AquireResource2()) return deinitFunc(TERM_2);
    if (!AquireResource3()) return deinitFunc(TERM_3);
    return 0;
    }

    int deinitFunc(state = TERM_ALL) // Cheating with C++
    {
            switch (state)
            {
                    case TERM_ALL:
                    case TERM_3:
                            Cleanup3(); // lint intentional pass-through
                    case TERM_2:
                            Cleanup2(); // lint intentional pass-through
                    case TERM_1:
                            Cleanup1(); // lint intentional pass-through
            }
            return -1;
    }

    I personally prefer the gotos but some people don't. I had to do the above pattern for something with a 24 step initialization process. Not all steps allocated resources of course but all of them could fail. The lead programmer hated gotos, so I had to do it that way. Which was also beneficial because I no longer needed to create a separate deinit function. To me it looks the same as gotos, *shrug* but to each their own.

    I have used gotos in other cases. Mainly in driver development. I had something like 10 us between transmissions on a SPI bus and was trying to shrink that down. I replaced a continue with a goto and it saved me 90 ns. Made the code look horrible and ripped the goto out again to look for other ways to solve the problems. But sometimes when your optimizing and fighting for ns gotos are what's needed.

    --
    Software Engineer & Writer of Military Science Fiction and Fantasy Blog: petermwright.com Twitter: WrightPeterM
  141. Goto and longjmp() by spaceyhackerlady · · Score: 1

    My use of goto sounds like everybody else's: if(something_bad_has_happened) goto code_to_fix_it;

    In highly modular code with lots of procedures the "goto" may end up as a longjmp(). So be it.

    ...laura

  142. Re:GOTO is a crutch for bad programmers by tepples · · Score: 1

    I'd like you to show an example of goto refactored to switch/case and goto refactored to function calls, so that others can show a counterexample.

  143. Abuse by Livius · · Score: 1

    goto is open to abuse.

    Rigid prohibition of goto is also open to abuse.

  144. Resource leaks by tepples · · Score: 1

    Which leaks all the resources that you had allocated prior to this check. The goto cleanup; idiom is intended to ensure those resources are deallocated. In this way, it's like the finally clause of a try block in Java or Python.

  145. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Deep nesting is not "cleaner."

  146. ScummVM's switch by tepples · · Score: 1

    So you have macros that transform a coroutine into a big switch statement, selecting on the source code line numbers on which yield statements appear, and putting all the function's local variables in a struct. I guess that's one way to do it. But how well does it work when there are switch statements within the coroutine itself?

  147. Re:GOTO is a crutch for bad programmers by angel'o'sphere · · Score: 1

    Of course you can and you are supposed to do so.
    For that the inventor invented public and private functions (and yes, that concept exists in C, too!)
    Nearly all examples in this article I had refactored into multiple functions/methods, so had more or less any programmer I ever worked with.

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  148. Re:GOTO is a crutch for bad programmers by bobbied · · Score: 1

    What part of "rule of thumb" do you not get? There are times when it's done, but it should be avoided.

    The reason is easy to get if you think about it. Functions start at the top and should end at the bottom... Returns in between are (generally) "bad form" because it's easy to miss them when looking at the source code.

    BTW, this applies double when you are actually returning a value to the caller... Still there are exceptions, but in general, one return, at the bottom, is best.

    Here is your reference... http://en.wikipedia.org/wiki/R...

    --
    "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
  149. Re:GOTO is a crutch for bad programmers by angel'o'sphere · · Score: 1

    That never was a rule.
    Someone posted it somewhere and some people believed it.
    I know no programmer who followed such an idiotic idea.

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  150. Takeing out goto's is a logical fancy by Anonymous Coward · · Score: 0

    Dumb programers misuse goto's.. therefor we take goto's out of the lang, and now we have smart programers wright ?
    No.. You still have dumb programers,which will screw up in some other way.
    it's a simple logical fancy.
         

  151. Re: GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Lots of macros to hide the scary gotos and make them look like regular try catch blocks?

    Them gotos are evil!

  152. Re:GOTO is a crutch for bad programmers by dwpro · · Score: 1

                Dim numsToClean As New List(Of Integer)
                For indx = 1 To 3
                    If Not AquireResource(indx) Then
                        Cleanup(numsToClean)
                        Return
                    End If
                    numsToClean.Add(indx)
                Next

                DoStuffWithResources()

                Cleanup(numsToClean)

    --
    Millions long for immortality who do not know what to do with themselves on a rainy Sunday afternoon. -- Susan Ertz
  153. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Amen

  154. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    no

  155. Re:GOTO is a crutch for bad programmers by ShanghaiBill · · Score: 1

    Deep nesting is not "cleaner."

    Deep nesting and "goto"s are both symptoms of poor design, so you shouldn't be using either. Instead a complex function should be split up into logical segments that are implemented as separate subroutines, that each perform a clear and well defined task.

  156. Re:GOTO is a crutch for bad programmers by bobbied · · Score: 1

    Don't know much then eh? http://en.wikipedia.org/wiki/R...

    It's been a topic of debate for decades, right up there with the GOTO thing... Actually they are generally the SAME arguments either way, but hey.... Who am I?

    --
    "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
  157. Re:if (i_use_GOTOs) { goto_school(); } by Anonymous Coward · · Score: 0

    > Please explain how else to handle error conditions sanely in C? For example, how do you cleanly implement a function that needs to acquire N resources where any one of the acquisitions can fail and on failure you need to clean up after yourself?

    If, say, a malloc() fails then it will return a null. In the clean up just test the pointer and only free if not null.

    How hard is that ?

  158. Re:GOTO is a crutch for bad programmers by Qzukk · · Score: 1

    This compiles in my head (it's been a looooong time since I last touched C) and uses three allocations and several places that can fail.

    /* Write no more than 1024 bytes to a new file.txt */
    if (-1 != (dest = creat("file.txt", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP))) {
      if (-1 != (src = open("source.txt"))) {
        if (NULL != (buf = calloc(1024, 1))) {
          if (-1 != (rd = read(src, buf, 1024))) { /* should reading zero bytes be an error? */
            total_written = 0;
            buf_p = buf;
            break_loop = 0; /* because break is just another name for goto */
            while (total_written < rd && !break_loop) {
              if (-1 != (wr = write(dest, buf_p, rd-total_written))) {
                total_written += wr;
                buf_p += wr;
              } else {
                break_loop = 1; /* TODO check errno for fixable errors like EAGAIN or EINTR */
                perror("Error writing to file");
              }
            }
          } else {
            perror("Read failed");
          }
          free(buf);
        } else {
          perror("Memory allocation error");
        }
        close(src);
      } else {
        perror("Unable to open source.txt");
      }
      close(dest);
    } else {
      perror("Unable to create file.txt");
    }

    Feel free to bash and/or offer constructive criticism. There's probably some official order to how things should be allocated but I don't know what it is. Maybe memory and sourcefile should have come first to minimize filesystem impact. First thought is that the loop in the middle could be moved to a function to move x bytes from file a to file b using buffer c which relies on x a b c correctness instead of testing it.

    --
    If I have been able to see further than others, it is because I bought a pair of binoculars.
  159. Re:GOTO is a crutch for bad programmers by BarbaraHudson · · Score: 1

    It might be a "rule of thumb" but some of us aren't all thumbs. Returns in switch statements when no resource allocation has yet been done are clean and clear.

    --
    "Transparent" is a shit show that trades on every stereotype going. A man in drag is NOT a transsexual.
  160. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    The key point is how many lines of resource allocation and clean up are required. If resource allocation and clean up are one line each then some nested if's are fine. But if the resource allocation and clean up are both huge chunks of code then breaking it out into separate functions is better.

  161. SOOOO satisfying by cfalcon · · Score: 1

    It's so satisfying to see research like this. Every goto is this miniature jihad of people who are scared of it getting out their pikes, every piece of code that should use it making you wonder "am I gonna get raked over the coals? is this battle worth it?".

    Hopefully the appropriate use of unconditional jump in mid and high level code will be appraised based on whether it's correct and good, not based on snap judgments and zealots.

    Christmas in February IMO.

  162. SOOOO satisfying by cfalcon · · Score: 1

    Research like this is very satisfying. Every correct use of goto is like "will I face jihad over this? Is it worth fighting this battle?".

    Maybe in the future we'll see less anti-goto zealotry crapping on the correct uses of goto.

    Christmas in February IMO.

  163. Re:GOTO is a crutch for bad programmers by angel'o'sphere · · Score: 1

    Well, and who am I?
    I don't care what idiots wrote into wikipedia.
    Where I worked the last 35 years people return immediately with the result from the function, just like a mathematician would write it.
    If you would adhere to a stupid 'only one return' rule you likely would be dragged into the basement and punished :D

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  164. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    The real question is, if someone writes the goto thing above, are you gonna scream at them until they triangle it?

    If so, I think you are fighting a religious war for no reason.

  165. Re:GOTO is a crutch for bad programmers by AaronW · · Score: 1

    Try 80 columns using the Linux kernel coding convention using 8-character tabs for indentation. The code grows unreadable quite fast.

    --
    This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
  166. Re: GOTO is a crutch for bad programmers by AaronW · · Score: 1

    Try using C++ in the Linux kernel or in a bootloader, the type of stuff I work on. Everything is C for a reason. That isn't to say that C++ can't be used at the kernel level since I worked on a large C++ OS/2 driver (around 100KLOC) years ago, but it took a lot of work to make C++ work in that case and it was extremely compiler dependent (I think it only worked with Watcom 10.0b, not rev c or any other version).

    --
    This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
  167. Goto Fail; by arglebargle_xiv · · Score: 1

    (Body added because Slashspot won't let me post a subject-only post, which has now ruined some of its effectiveness).

  168. Re:GOTO is a crutch for bad programmers by AaronW · · Score: 1

    And that non-standard indentation will cause nothing but trouble, especially in a large project. The lack of proper indentation makes the code harder to read than just using a goto, especially if someone works on it in a modern editor that does things like handling indentation for you.

    --
    This post is encrypted twice with ROT-13. Documenting or attempting to crack this encryption is illegal.
  169. Re:if (i_use_GOTOs) { goto_school(); } by jschultz410 · · Score: 1

    Write an example that properly handles 5 different mallocs within the same function and properly cleans up after itself on failure without using goto's. Here's the goto example:

    Resources *Resources_alloc(void)
    {
        Resources *ret;

        if (NULL == (ret = malloc(sizeof(Resources))))
            goto FAIL;

        if (NULL == (ret->rsrc1 = malloc(sizeof(ret->rsrc1))))
            goto FAIL_RESOURCES;

        if (NULL == (ret->rsrc2 = malloc(sizeof(ret->rsrc2))))
            goto FAIL_RSRC1;

        if (NULL == (ret->rsrc3 = malloc(sizeof(ret->rsrc3))))
            goto FAIL_RSRC2;

        if (NULL == (ret->rsrc4 = malloc(sizeof(ret->rsrc4))))
            goto FAIL_RSRC3;

        assert(ret);
        goto END;

    /* error handling and return */

    FAIL_RSRC3:
        free(ret->rsrc3);

    FAIL_RSRC2:
        free(ret->rsrc2);

    FAIL_RSRC1:
        free(ret->rsrc1);

    FAIL_RESOURCES:
        free(ret);
        ret = NULL;

    FAIL:
        assert(!ret);

    END:
        return ret;
    }

    Also, it isn't always the case that the thing you need to reclaim is a pointer and can be dynamically tested as to whether it was successfully acquired or not. For example, you can't test a pthread_mutex_t to see if it is valid or not. Your code has to know either based on its structure (i.e. - like the above) or you have to have a separate tracking variable per such object.

    PS - Yes, the example is a bit contrived, there'd be little reason to malloc those members rather than just have them allocated as part of the Resources struct. I just did that as an illustrative example. Also, I'd typically cast the result of a malloc to the appropriate type so that a C++ compiler wouldn't complain about my code, but I haven't specified their types in this example.

  170. Goto the exception not the rule ... by perpenso · · Score: 1

    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.

    The problem is goto is not just used in the "heinous" nesting cases. And "heinous" varies with the length of the conditional blocks. If there are many levels but it fits on a screen or two, perhaps leans toward if. If they are stretching for many screens worth of code maybe lean towards goto.

    The problem with goto is that the conditional code is at the same nesting level as the unconditional code so it makes it less apparent what code is conditional. Using goto should be the exception, to substitute a smaller problem for a larger problem, not the rule, substituting a small problem for no existing problem at all (minor nesting for short durations).

  171. Re:GOTO is a crutch for bad programmers by bobbied · · Score: 1

    Returns in switch statements when no resource allocation has yet been done are clean and clear.

    To quote myself from my previous post...

    Still there are exceptions, but in general, one return, at the bottom, is best.

    Yes, there ARE exceptions and I've done it too, usually for error cases where the function simply cannot continue, but in most cases, one return is all you need or want.

    So what exactly have you DONE with your thumbs? On second thought, I don't want to know.

    --
    "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
  172. Re:GOTO is a crutch for bad programmers by bobbied · · Score: 1

    Yea, well I learned to do structured program in PASCAL so I guess my roots are showing, well that and assembly where "return from subroutine" happened willy nilly at times, just like "Jump" (aka GOTO) and was a source of much agony for the careless...

    Feel free to write as many returns and GOTOs into your functions as you want cause as one ole fart to another... I personally don't care HOW you wrote it as long as it runs and I don't have fix it for you. Unless you are working for me, in which case you might find yourself reading a pesky coding standard designed to scrape the rough edges off your habits so the next guy I hire can actually fix your mess after you are gone.

    --
    "File to fit, pound to insert, paint to match" - Aircraft Maintenance 101
  173. When performance is part of correctness by tepples · · Score: 1

    I'm working on a chip with extremely limited memory. We run out long before the project is working well enough for even a demo, so we must start optimizing for space before it's correct or understandable.

    If you've run out of memory before you've run out of steps in the algorithm, you first do the profiling to see how many bytes each method takes. Then you size-optimize the parts that are correct (per your unit tests) and leave the parts that aren't correct for later.

    There are other cases I've had in the past where a real time deadline can't be met without doing some optimization (which generally means stop coding the naive way). [...] Not optimizing prematurely means doing a linear search through an array instead of using a built in function or data structure that is more efficient.

    You bring up a good point. In the case of gross inefficiency causing your real-time program to miss deadlines, performance is part of correctness because missing deadlines is an integration test failure. After you do the profiling to see what's using so much time, you can put together unit tests that check inner loops for reasonable performance, and then you can optimize for both logical correctness and performance correctness.

  174. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    void func() {
        if (AquireResource1()) {
            if (AcquireResource2()) {
                if (AcquireResource3()) {
                    DoStuffWithResources();
                    Cleanup3();
                }
                Cleanup2();
            }
            Cleanup1();
        }
    }

  175. Re:GOTO is a crutch for bad programmers by stafil · · Score: 1

    With 4-spaces for code indentation and the usual 80chars long line limitation, the readability becomes ridiculous.

    +1 for goto.


    if ((not_too_long_a = a_bit_longer_resource_a()) != NULL) {
        if ((not_too_long_b = a_bit_longer_resource_b()) != NULL) {
            if ((not_too_long_c = a_bit_longer_resource_c()) != NULL) {
                if ((not_too_long_d = a_bit_longer_resource_d()) != NULL) {
                    if ((not_too_long_e = a_bit_longer_resource_e()) != NULL) {
                        if (lets_try_to_add_some_logic_too == not_unusual) {
                            if (we_are_almost_out_of_space) {
                                oh_shit_we_are_running_out_of_space(we_have_a_variable_here, and_another_v

     

  176. Re:GOTO is a crutch for bad programmers by jschultz410 · · Score: 1

    How about the contrived example of you actually specifying what acquireResources() should look like in C?

  177. Re:GOTO is a crutch for bad programmers by BarbaraHudson · · Score: 1

    Notice that my example was NOT for error-handing, which is the usual excuse. GOTO is fine, same as JMP, JNE, JLE, etc.

    Do you also think that one-line ternary expressions are bad (or chained ternary expressions)? Or that people should code it as if(1==x) instead of if(x==1) because they might forget to use the second equal sign? I "get" the logic behind both, but experience fixes those problems.

    I have my style of coding, and if you ask 10 programmers what the ideal style is, you'll get back 11 (or more) opinions. It's no big deal :-)

    --
    "Transparent" is a shit show that trades on every stereotype going. A man in drag is NOT a transsexual.
  178. Re:GOTO is a crutch for bad programmers by jschultz410 · · Score: 1

    Here's an alternate form that uses goto's:

    {
        if (-1 != (dest = creat("file.txt", S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP))) {
            perror("Unable to create file.txt");
            goto FAIL;
        }

        if (-1 != (src = open("source.txt"))) {
            perror("Unable to open source.txt");
            goto FAIL_DEST;
        }

        if (NULL != (buf = calloc(1024, 1))) {
            perror("Memory allocation error");
            goto FAIL_SRC;
        }

        if (-1 != (rd = read(src, buf, 1024))) { /* should reading zero bytes be an error? */
            perror("Read failed");
            goto FAIL_BUF;
        }

        for (total_written = 0; total_written < rd; total_written += wr, buf_p += wr) {
            if (-1 == (wr = write(dest, buf_p, rd-total_written))) { /* TODO check errno for fixable errors like EAGAIN or EINTR */
                perror("Error writing to file");
                goto FAIL_BUF;
            }
        }

    FAIL_BUF:
        free(buf);

    FAIL_SRC:
        close(src);

    FAIL_DEST:
        close(dest);

    FAIL:
    }

    I prefer this form because the main line execution is significantly clearer (i.e. - you don't have ever deeper nesting of the successful path), especially if you have even more resources to acquire that can fail. Also, errors are handled immediately (e.g. - the associated perror() is right there where the error is detected rather than potentially hundreds of lines below) and the main line of execution is obviously aborted and cast off to error handling / cleanup code.

    An even better example would be an initializer function that only releases the acquired resources on error and on success leaves them acquired when it returns. There, the if-else structure you used won't work -- or your successful return is buried deep inside your nested successful if's with a different exit point for errors.

  179. Re: GOTO is a crutch for bad programmers by jschultz410 · · Score: 1

    C++ has FAR too many evil temptations in it to be allowed in many situations: the sword itself incites to violence.
    C is far simpler and easy to understand what is happening.

  180. Re:GOTO is a crutch for bad programmers by jschultz410 · · Score: 1

    Sure but that doesn't help people programming in C. You might as well tell them to program in Lisp because it's better.

  181. Multi level break and other language constructs. by Anonymous Coward · · Score: 0

    Goto is useful for implementing constructs that are missing. I don't know if this has been resolved in modern C, but I do remember that older versions at least are missing a multi-level break statement.

    break 3;

    For example, should break out of loops 3 layers of control loops. Documented properly, this is one example of a goto. I also agree with other commentators that in a language where you can throw/raise an exception that gotos very likely don't have a use; you already have a pattern for breaking out of normal flow and jumping in to some error handling routine.

  182. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    if (!AquireResource1()) return;
    if (!AquireResource2()) { Cleanup1(); return }
    if (!AquireResource3()) { Cleanup2(); Cleanup1(); return }

    DoStuffWithResources();

    }

    it's about the same to me.

  183. Re:GOTO is a crutch for bad programmers by sysrammer · · Score: 1

    Your last place would have found greenbar printouts useful.

    --
    His ignorance covered the whole earth like a blanket, and there was hardly a hole in it anywhere. - Mark Twain
  184. Re:GOTO is a crutch for bad programmers by angel'o'sphere · · Score: 1

    As I said in another post, I never had the need to use a goto since I don't program in Fortran (Cyber 205) nor Basic (Apple ][) anymore.

    --
    Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
  185. goto used in Linux kernel extensively by Anonymous Coward · · Score: 0


    linux-3.16-rc5 # grep -r "goto" | wc -l
    116607

    From Documentation/CodingStyle:

    Albeit deprecated by some people, the equivalent of the goto statement is
    used frequently by compilers in form of the unconditional jump instruction.

    The goto statement comes in handy when a function exits from multiple
    locations and some common work such as cleanup has to be done. If there is no
    cleanup needed then just return directly.

    The rationale is:

    - unconditional statements are easier to understand and follow
    - nesting is reduced
    - errors by not updating individual exit points when making
            modifications are prevented
    - saves the compiler work to optimize redundant code away ;)

    example:

            if (id < 0) {
                    id = ida_simple_get(&rtc_ida, 0, 0, GFP_KERNEL);
                    if (id < 0) {
                            err = id;
                            goto exit;
                    }
            }

            rtc = kzalloc(sizeof(struct rtc_device), GFP_KERNEL);
            if (rtc == NULL) {
                    err = -ENOMEM;
                    goto exit_ida;
            }

    [.......]

    exit_kfree:
            kfree(rtc);

    exit_ida:
            ida_simple_remove(&rtc_ida, id);

    exit:
            dev_err(dev, "rtc core: unable to register %s, err = %d\n",
                            name, err);
            return ERR_PTR(err);

  186. Never Use Goto by Old+Aylesburian · · Score: 1

    I have written a hell of a lot of c and c++ in the last quarter of a century and have never used goto. I have used setjmp/longjmp though.

    1. Re:Never Use Goto by jschultz410 · · Score: 1

      Then how do you cleanly handle a function that needs to acquire N resources where any one of the acquisitions can fail -- and it needs to clean itself up on failure (and possibly on success)?

      The only non-goto answer I've seen so far is to have ever deeper nesting of if's (with a return buried in its depths if the resources should be held on success), followed by a bunch of unwinding else's that contain and separate the error handling in else's and far away from the error detection (with a different return path when the resources are held on success).

      Such coding contains a bunch of anti-patterns: ArrowAntiPattern and rejects the use of GuardClauses and HandleErrorsInContext.

      Meanwhile, the goto version does exactly the opposite -- it doesn't have ever deeper nesting of the common successful path, it uses guard clauses to abort further execution upon error detection, error dispatching (and any in context handling if necessary) is easily done and you can jump to exactly the right section of cleanup code and it is easy to have a single exit point for the function after all the cleanup code at the bottom of the function.

    2. Re:Never Use Goto by Old+Aylesburian · · Score: 1

      I don't recall ever handling an N greater than one (mostly malloc/free), but would probably continue as at present where a block that reserves a resource also releases it at the same level of nesting. I don't always keep to the single entry/single exit paradigm, but would in this case. Using a goto would make it easy to accidentally skip the release and thereby cause resource leakage.

  187. Problems with exceptions by Anonymous Coward · · Score: 0

    The problem with exceptions is that you have to hold distant code (the exception handler) in your mind along with the code causing the exception.

    The reason why GOTO was considered bad code was because you had to hold a map of where the code gone to was and what the code was doing before it went there.

    I.e. the same damn problem.

    ALL programming necessities are so that you have code that can be understood easily. Extending it requires understanding. Refactoring (which will be necessary after sufficient numbers of extension for any code) requires understanding.

  188. Why bother with the nesting? by Anonymous Coward · · Score: 0

    I've never understood the "deep nesting" thing. Just do this:

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

  189. So even white collar jobs are wage slaves. by Anonymous Coward · · Score: 0

    If You don't think it's possible without independent wealth to walk away from a job then you're admitting our capitalist system is working off slave labour.

    Well done, sheep.

    1. Re:So even white collar jobs are wage slaves. by mark-t · · Score: 1

      Of course it's *POSSIBLE*.... just not necessarily practical. Particularly when you want to do things like eating, or just continuing to have a place to live.

      For people who have developed enough social and networking skills that they can successfully make a living being self-employed, of course they can walk away from a job at anytime, even without being independently wealthy, because they have something else to fall back on without facing the risk of destitution.

      I would disagree with the assertion that the lack of ability to do such a thing makes me a sheep.

    2. Re:So even white collar jobs are wage slaves. by Anonymous Coward · · Score: 0

      So why did you reply to ME with it being possible to leave a job, AND NOT THE PARENT POST I replied to? Oh, right, that was you. So why the fucking hell do you whine at me about how it must be so nice I can walk away from a job being so independently wealthy WHEN YOU THEN COME BACK AND CLAIM IT'S NOT NECESSARY????

      Oh right, because you are a moron.

    3. Re:So even white collar jobs are wage slaves. by mark-t · · Score: 1

      There is a difference between what may be theoretically possible for some people to do and what is actually practical for most people to do.

      However, if you cannot debate with someone who might suggest that your recommendations may not be practical for a large number of people without resorting to name calling like "fool", "sheep", or "moron", then we are probably done here.

  190. Re:if (i_use_GOTOs) { goto_school(); } by bro2 · · Score: 1

    "GOTO" should never have been allowed in C.

    That is a silly statement. There are always someone able to abuse even the safest constructs, so removing any "unsafe" construct is not the solution. Teaching how not to use them, is however, a much better strategy.

  191. GOTO Forward, GOTO Back, GOTO Forw... by Anonymous Coward · · Score: 0

    Maybe programmers prefer to read code in a linear fashion, rather than a Choose-Your-Own-Adventure book.

    1. Re:GOTO Forward, GOTO Back, GOTO Forw... by narcc · · Score: 1

      The how do you explain the popularity of OOP?

  192. Everything is built on Gotos by foreverdisillusioned · · Score: 1

    In my last job I was dealing with a lot of extremely complicated Excel and Access macros written by finance majors. Smart people, but people who had zero formal programming experience. I opened up a module one day and this is what I saw:

    if foo1 then [VBA requires a "then"]
    bar1
    Goto Label1
    end if
    bat1
    Label1:

    if foo2 then
    bar2
    Goto Label2
    end if
    bat2
    Label2:


    I stared at my screen for probably ten whole seconds and then began laughing uncontrollably, then kept laughing as I alternated shaking my head and occasionally shrugging in halfhearted approval. The guy invented an else. He didn't know about the existing else so he found a simple "design pattern" that did what he needed and used it. Once you got over the initial ridiculousness, it was pretty easy to follow.

    And that *is* all that an "if" is: a species of goto. So are continuations. So are a lot of other control structures. This sentiment--"you shouldn't use a Goto when it is simple and intuitive; instead, you should use a bunch of conditional Gotos in an unintuitive way"--is completely incomprehensible to me. It's not merely saying 'never taking off the training wheels; it's saying, "if the training wheels make a certain turn in the path too difficult, just get off the bike, pick it up, gently turn it where it needs to go, and hop back on." If large projects with code monkeys require tons of least-common-denominator idiotproofing, so be it. But competent experts are not wrong to say that sometimes you need to take off the training wheels. I've yet to hear a coherent argument about the wrongness of Goto that doesn't boil down to "this is what I was always taught", "I'm not imaginative enough to think of a use case", or "you have to prevent stupid programming from doing stupid things."

  193. Re:GOTO is a crutch for bad programmers by KlomDark · · Score: 1

    In other words, you are just an arrogant bastard with no good answer.

  194. Re:GOTO is a crutch for bad programmers by MagickalMyst · · Score: 1

    Sure.

    --
    Political correctness is really just herd psychology pushed by insecure people who desperately seek social conformity.
  195. Natural Structured Programming by Doctrinsograce · · Score: 1

    Sheesh... kids... The proscription of GOTO was a general principle. Some languages did not adequately accommodate single-entrance-single-exit. Therefore, branching to an exit statement was never considered a violation of structured programming. Of course, if the language in question DOES have the appropriate construct -- as does C and its variants -- then the use of GOTO would be frowned upon. As one of my instructors, back in the day, used to say, "If you have to GOTO, then ask yourself why you aren't there already."

  196. Re:GOTO is a crutch for bad programmers by Anonymous Coward · · Score: 0

    Not different, but refined:

    #define TRY(_cond,_status,_exitpoint,_msg...) \
    do { if (_cond) { \
              status=(_status); \
              printf("Failed whlie " _msg); \
              goto _exitpoint; \
      } } while(0)

    void func() {
    int status=0;

    TRY(!AquireResource1(), -1, end, "acquiring resource 1");
    TRY(!AquireResource2(), -1, cleanup1, "acquiring resource 2");
    TRY(!AquireResource3(), -1, cleanup2, "acquiring resource 3");

    DoStuffWithResources();

    TRY(!Cleanup3(), -2, panic, "releasing resource 3");
    cleanup2:
    TRY(!Cleanup2(), -2, panic, "releasing resource 2");
    cleanup1:
    TRY(!Cleanup1(), -2, panic, "releasing resource 1");

    end:
    panic:
    return status;
    }

    Advantages:
    * Boils code down to its essence ("if" and "goto" are actually *boilerplate* when you follow the idiom.)
    * Lends itself to consistent use
    * Actually *useful* (as in, "not merely cosmetic") code documentation
    * Every "important" is wrapped with a macro(!!!); If you apply this idiom consistently, you can instrument the wazoo out of your code, post-implementation, with things like tracing, backtracing, and all kinds of crazy stuff like single-stepping (use a semaphore) or whatever you can imagine, all throughout your code, by simply changing the definition of the TRY macro.

  197. Comment removed by account_deleted · · Score: 1

    Comment removed based on user account deletion

  198. Re:Stenography when used well; steganography when by The+New+Guy+2.0 · · Score: 1

    I think "designed" was my word error. GOTO was invented to make sense to the processor, but it's use combined with functions ended its time as the best idea to use.

  199. Re:GOTO is a crutch for bad programmers by shutdown+-p+now · · Score: 1

    Oh?

    #define skipto goto ...
    skipto cleanup;

    That makes you happy then?

  200. Re:GOTO is a crutch for bad programmers by shutdown+-p+now · · Score: 1

    Do you seriously think this is cleaner? Especially when in practice the resource-acquisition functions can be called in different order (or not at all) on different code paths depending on what gets returned by other functions?

  201. Re:GOTO is a crutch for bad programmers by kleinesRaedchen · · Score: 1

    How 'bout (or were functions ruled out?):

    void func() {
    if (AquireResource1())
    func2();
    }

    void func2() {
    if (AquireResource2())
    func3();
    Cleanup1();
    }

    void func3() {
    if (AquireResource3()) {
    DoStuffWithResources();
    Cleanup3();
    }
    Cleanup2();
    }

  202. Re:GOTO is a crutch for bad programmers by MagickalMyst · · Score: 1

    Ecstatic.

    --
    Political correctness is really just herd psychology pushed by insecure people who desperately seek social conformity.
  203. O RLY??? by NoNonAlphaCharsHere · · Score: 1


  204. Why goto is sometimes OK by herbierobinson · · Score: 1

    By and large goto is OK when used as an exit path from a nested context (as others here have shown in examples). Some languages provide explicit constructs for this (like variants or exit and continue that allow one to specify which nested context is being exited). C doesn't have these; so, one has to make do.

    BTW, if you want to know what's bad about gotos, track down some Fortran programs that were written in the 60s and you will see where Dijkstra was coming from :-)

    --
    An engineer who ran for Congress. http://herbrobinson.us
  205. If you like your GOTO... by srbell · · Score: 1

    If you like your GOTO you can KEEP your GOTO