Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. The Weird and The Wonderful
  4. Gotoless programming

Gotoless programming

Scheduled Pinned Locked Moved The Weird and The Wonderful
73 Posts 47 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A andrewgissing

    Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.

    P Offline
    P Offline
    Plamen Dragiyski
    wrote on last edited by
    #60

    If I'm not sure will compiler will understand goto's replacement better, I prefer goto (never trust any compiler).

    1 Reply Last reply
    0
    • C ClockMeister

      CDP1802 wrote:

      Thinking and making most of the resources at your disposal is more important than blindly following rules.

      Well said. My thoughts exactly. It's a matter of the right tool for the job. This is true in any field of endeavor. You use a spoon when you need one and a front-end loader when you need one of those. You don't just say "never use a spoon" once you've discovered that you have a front-end loader at your disposal. You use whichever one suits the job at hand. GOTO makes sense in a lot of contexts, in others it doesn't. Whatever construct allows you to express the idea in code most elegantly is what you use. I have to laugh at the religious fervor that develops over this particular subject. -Max

      J Offline
      J Offline
      jschell
      wrote on last edited by
      #61

      CodeBubba wrote:

      OTO makes sense in a lot of contexts, in others it doesn't.

      I doubt that in the general sense and specifically for this site/forum. It could be that there is a problem domain like camera firmware where the context basically requires goto. However in the context of standard enterprise business development that is done in languages like Java, C# and/or C++ it almost never is needed.

      1 Reply Last reply
      0
      • M Mark Kruger

        Good example exactly of not using goto at all, it's easily converted to an if then else situation. which increases readability if u would ask me.

        while(settext())
        {
        // Command 1 (no parameters)
        if(!stricmp(text, "something"))
        {
        DoStuff();
        // continue; // Skip command 2-3 & error check
        }

        // Command 2 (single parameter - text to match)
        else if(!strincmp(text, sizeof("other thing ")-1, "other thing "))
        {
        for(unsigned int i = 0; i < StringArray.size(); ++i)
        {
        if(!stricmp(text+sizeof("other thing ")-1, StringArray[i]))
        {
        StringArray.erase(i);
        break; // or use goto JumpHere?
        }
        }

          // Did not find? You have to use a variable to check
          ReportError("parameter not found");
        

        // continue; // Skip command 3 & error check
        }

        // Command 3 (not set up)
        else if(!stricmp(text, "asparagus"))
        {
        // continue; // Skip error check
        }
        else

        {
        // Error check
        ReportError("command not found");
        // JumpHere:
        // continue; // Labels must have a statement
        }
        }

        S Offline
        S Offline
        SortaCore
        wrote on last edited by
        #62

        I believe you read that wrong, please read the comments I have in the code. The point here was exiting out of the the for loop embedded in the while loop, not the if format ;) Although I am also interested if using if-else-if actually is faster than repetitive

        if() {code(); end_if_checks();} if() {...}

        in my example though.

        M 1 Reply Last reply
        0
        • S SortaCore

          I believe you read that wrong, please read the comments I have in the code. The point here was exiting out of the the for loop embedded in the while loop, not the if format ;) Although I am also interested if using if-else-if actually is faster than repetitive

          if() {code(); end_if_checks();} if() {...}

          in my example though.

          M Offline
          M Offline
          Mark Kruger
          wrote on last edited by
          #63

          If u want speed, i would const the size of for your fixed string, would safe u getting it's length each time u go for another loop in the while. The continues u fire are at end of each if slice, and in an if else construction it would jump out to bottom anyways, so in this case i think continue actually will be equally fast at best and else even slower.

          for(unsigned int i = 0; i < StringArray.size(); ++i)
          {
          if(!stricmp(text+sizeof("other thing ")-1, StringArray[i]))
          {
          StringArray.erase(i);
          break; // or use goto JumpHere?
          }
          }

          I normally do different, a bit slower i assume but clear

          //somewhere outside the while
          const int Sizer = sizeof("other thing ")-1;
          //

          int WalkTo = StringArray.size() - 1;

          if (WalkTo >= 0)
          {
          const char* Check = text + Sizer;
          int i = -1;
          int Found = 0;

          do
          {
             i++;
             if (!stricmp(Check, StringArray\[i\]))
             {
                 StringArray.erase(i);
                 Found = 1;
             }
          } while (!Found && (i < WalkTo));
          

          }

          S 1 Reply Last reply
          0
          • A Ahmedn1

            The main problem is that goto statement is the only instruction in all programming languages that can change the PC (Program Counter) register in the processor and this is not right

            B Offline
            B Offline
            BobJanova
            wrote on last edited by
            #64

            Clearly false since a whole bunch of language constructs compile into assembler/IL jump instructions.

            1 Reply Last reply
            0
            • L Lost User

              The good old goto debate. A goto is a bit like telling the computer that I don't want you to proceed to the next line of code, instead make some other line the next thing to execute. And we do that all the time: exit for, exit do, if some condition goto next line otherwise goto some other line. While some condition go into first line of loop block otherwise goto past the end of the loop block. And then, it all eventually becomes machine code / opcodes, and all of these become some kind of jump instruction, which is basically a goto. So for all you people out there that think that your code has no gotos, I can assure you the CPU is doing jump instructions left, right and centre as YOUR code runs in the CPU. Now please don't tell me that your code is somehow bypassing the CPU. The reason this myth exists is that those early versions of BASIC had line numbers for each statement. And you would code "GOTO 760". Problem was when you inserted lines and made 760 line 761 or whatever but didn't go and update everything pointing to 760. And so this caused problems and bugs. Let's move on. We have alphabetic statement labels (used all the time in assembly language by the way), so you can now "Goto SomeLabelThatHasAMeaningfulNameThatWontBeRenumbered" and the problem is gone. Use goto freely, it's OK. I do it. It gets me out of deep nested rules and condition logic where I have established something I needed to establish. Yes there are always other ways to achieve the same result, but no - they are not always better or more elegant. And now it is time for me to go to bed.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #65

              This is a simplistic example of the sort of thing I am talking about. My sympathies to those of you who find it un-structured, hard to understand, un-clean or bad code. Let me see yours.

              if WageEarner then
              WeeklyPay = HrsWorked * Rate
              Goto WklyPayDetermined
              end if
              if SalaryEearner then
              WeeklyPay = (Salary * 7) / 365
              Goto WklyPayDetermined
              end if
              if FutureHire then
              WeeklyPay = 0
              Goto WklyPayDetermined
              end if
              if Retired then
              if WasWageEarner then
              WeeklyPay = FinalRate * 40 * 0.5
              Goto WklyPayDetermined
              else
              WeeklyPay = 0.6 * (Salary * 7) / 365
              Goto WklyPayDetermined
              end if
              end if

              WklyPayDetermined:

              TaxDeductible = WorkOutTax(WeeklyPay)

              CreateBankTransaction(WeeklyPay - TaxDeductible)

              1 Reply Last reply
              0
              • M Mark Kruger

                If u want speed, i would const the size of for your fixed string, would safe u getting it's length each time u go for another loop in the while. The continues u fire are at end of each if slice, and in an if else construction it would jump out to bottom anyways, so in this case i think continue actually will be equally fast at best and else even slower.

                for(unsigned int i = 0; i < StringArray.size(); ++i)
                {
                if(!stricmp(text+sizeof("other thing ")-1, StringArray[i]))
                {
                StringArray.erase(i);
                break; // or use goto JumpHere?
                }
                }

                I normally do different, a bit slower i assume but clear

                //somewhere outside the while
                const int Sizer = sizeof("other thing ")-1;
                //

                int WalkTo = StringArray.size() - 1;

                if (WalkTo >= 0)
                {
                const char* Check = text + Sizer;
                int i = -1;
                int Found = 0;

                do
                {
                   i++;
                   if (!stricmp(Check, StringArray\[i\]))
                   {
                       StringArray.erase(i);
                       Found = 1;
                   }
                } while (!Found && (i < WalkTo));
                

                }

                S Offline
                S Offline
                SortaCore
                wrote on last edited by
                #66

                Okay, let me add a line at the prefix to clear up any confusion:

                std::vector StringArray;

                The StringArray.size() gets the size of an array of std::strings, not an array of chars. Say the StringArray was initialised to a set of usernames, in a server for example, and the command 2 could be "disconnect xxx".

                M 1 Reply Last reply
                0
                • S SortaCore

                  Okay, let me add a line at the prefix to clear up any confusion:

                  std::vector StringArray;

                  The StringArray.size() gets the size of an array of std::strings, not an array of chars. Say the StringArray was initialised to a set of usernames, in a server for example, and the command 2 could be "disconnect xxx".

                  M Offline
                  M Offline
                  Mark Kruger
                  wrote on last edited by
                  #67

                  Except that then u might want to retrieve the current size each loop what does it make it different for the rest? I see no different(new) reason to agree break is a good way to be honest.

                  1 Reply Last reply
                  0
                  • B BobJanova

                    The reason not to use goto is not a technical one, but a code cleanliness one. A goto is an unstructured jump and makes it much harder for a human brain to comprehend the structure of the procedure. Loops with breaks and continues, conditionals, switch blocks and so on may translate to jump instructions in assembler or IL, but they're structured and therefore easier to understand. The only time I would say it might be okay is the 'double break' (i.e. breaking out of a 2D or deeper loop set). When your logic is this complex it's usually better to take the looping code out into a sub-procedure or -function and use return instead, because chances are that procedure is too long already. (You can always ask the compiler to inline it if you think the function stack is critical.) In modern languages, proper error condition handling (i.e. exceptions) have taken away most of the situations in which you'd want to do this. So I agree up to a point: fundamentalist 'never' dictums (dicta?) are not particularly helpful. But it is very rarely the most elegant approach to use a goto.

                    L Offline
                    L Offline
                    Lost User
                    wrote on last edited by
                    #68

                    The point I was making was: use Goto when it is good to do so. That's a matter of judgement. It probably won't be often. But use it freely when you consider that it works well - when it simplifies or clarifies the logic flow. Don't be religious about following some rule that you heard somewhere. "Shoulds", "don'ts" and "nevers" are a poor substitute for judgement. The fool knows the answer, the wise man thinks.

                    1 Reply Last reply
                    0
                    • A andrewgissing

                      Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.

                      J Offline
                      J Offline
                      JamesSpencer
                      wrote on last edited by
                      #69

                      This is how a feel about goto exactly http://xkcd.com/292/[^]

                      1 Reply Last reply
                      0
                      • A andrewgissing

                        Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.

                        D Offline
                        D Offline
                        Duncan Goodwin
                        wrote on last edited by
                        #70

                        Anyone who has been around for a long time may remember that the GOTO-less programming controversy was laid to rest (in FORTRAN anyway) by an article published in the December 1973 issue of Datamation magazine. I kept a copy of that article all these years in my humour file as it proposed solving the problem by eliminating GOTO statements entirely and replacing them with the COME FROM statement. Here is an excerpt from the article entitled "A Linguistic Contribution to GOTO-less Programming" (Thanks to the miracle of the internet, the full article can now be found online at this link: http://www.fortran.com/come\_from.html ) --------------------------------------------------------- "This statement causes control to be transferred to the next statement (the statement immediately following the COME FROM) upon completion of the designated statement. Example: 10 J = 1 11 COME FROM 20 12 WRITE (6,40) J STOP 13 COME FROM 10 20 J = J+2 40 FORMAT (I4) Explanation: In this example, J is set to I by state- ment 10. Statement 13 then causes control to be passed to statement 20, which sets J to 3. Statement 11 then causes control to be passed to statement 12, which writes the current value of J. The STOP statement then terminates the program." ---------------------------------------------- In all seriousness, I have not had to use a goto statement in all the code I have written since the day that structured FORTRAN replaced FORTRAN IV on our mainframes in the early 80's. And I am including all the languages I have since used up until today: C, C++, PL/1, Java, C#, VB, Lisp, APL, and JavaScript. It is almost always possible to refactor logic that appears to require a goto into an equivalent form that doesn't. If your nesting is too deep, refactor into shorter, more succinct, and readable methods. Modern IDE's make refactoring dead easy and I have made extensive use of refactoring support in Eclipse as well as Visual Studio. But for any fans of computer history, do yourself a favour and read the entire article at the link above. Apologies for the Canadian (ie. British) spelling of 'humour' and 'favour'. I know they are somewhat anachronistic today, but that was how I was taught.

                        D 1 Reply Last reply
                        0
                        • D Duncan Goodwin

                          Anyone who has been around for a long time may remember that the GOTO-less programming controversy was laid to rest (in FORTRAN anyway) by an article published in the December 1973 issue of Datamation magazine. I kept a copy of that article all these years in my humour file as it proposed solving the problem by eliminating GOTO statements entirely and replacing them with the COME FROM statement. Here is an excerpt from the article entitled "A Linguistic Contribution to GOTO-less Programming" (Thanks to the miracle of the internet, the full article can now be found online at this link: http://www.fortran.com/come\_from.html ) --------------------------------------------------------- "This statement causes control to be transferred to the next statement (the statement immediately following the COME FROM) upon completion of the designated statement. Example: 10 J = 1 11 COME FROM 20 12 WRITE (6,40) J STOP 13 COME FROM 10 20 J = J+2 40 FORMAT (I4) Explanation: In this example, J is set to I by state- ment 10. Statement 13 then causes control to be passed to statement 20, which sets J to 3. Statement 11 then causes control to be passed to statement 12, which writes the current value of J. The STOP statement then terminates the program." ---------------------------------------------- In all seriousness, I have not had to use a goto statement in all the code I have written since the day that structured FORTRAN replaced FORTRAN IV on our mainframes in the early 80's. And I am including all the languages I have since used up until today: C, C++, PL/1, Java, C#, VB, Lisp, APL, and JavaScript. It is almost always possible to refactor logic that appears to require a goto into an equivalent form that doesn't. If your nesting is too deep, refactor into shorter, more succinct, and readable methods. Modern IDE's make refactoring dead easy and I have made extensive use of refactoring support in Eclipse as well as Visual Studio. But for any fans of computer history, do yourself a favour and read the entire article at the link above. Apologies for the Canadian (ie. British) spelling of 'humour' and 'favour'. I know they are somewhat anachronistic today, but that was how I was taught.

                          D Offline
                          D Offline
                          Duncan Goodwin
                          wrote on last edited by
                          #71

                          Ok, I lied...I just checked some of my FORTRAN source code written in 1985 and there were a handful of goto statements in 20,000 lines of code. But since FORTRAN, I have not used goto's (to the best of my knowledge :-)

                          1 Reply Last reply
                          0
                          • A andrewgissing

                            Inspired by the goto comments in the lounge today... Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company. His program had a main loop like: If var = 1 gosub 100 If var = 2 gosub 200 and so on.. and inside each subroutine before leaving, it would set var to whatever it needed to be next. An abstracted goto ! This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.

                            T Offline
                            T Offline
                            theMadCoder
                            wrote on last edited by
                            #72

                            Use a real language Just as a reminder BASIC = BEGINNERS All Purpose Instruction Code

                            1 Reply Last reply
                            0
                            • B BobJanova

                              Yes, if you're working in a language which doesn't support tail recursion. This goto (and the argument reassignments) should be clearly commented as being a hack around tail recursion not working, though.

                              R Offline
                              R Offline
                              Rachel Mant
                              wrote on last edited by
                              #73

                              Try working on a limited stack-depth platform, such as the PIC16F1516 - your tune will quickly change when you hit the stack depth with your precious function calls. Without goto on that platform you'd be royally f***ed for anything more than the simple. Tail recursion on a PIC: GOTO!

                              The worst thing about the darkness is the light at the end - DX-MON

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups