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. Avoid return statement in the middle - horror or not?

Avoid return statement in the middle - horror or not?

Scheduled Pinned Locked Moved The Weird and The Wonderful
question
59 Posts 28 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 Andrew Torrance

    Single exit , single entry . Its a mantra that leads to clarity how about if( !FlagA || !FlagB || !FlagC) // Select Variant on !Flagx or Flagx == false depending on language DoOtherThing(); else { if(PromptUser()) DoSomething(); } Not a horror though. My use of single entry and exit points in functions leads to more debates than anything. (My how the winter nights fly by)

    P Offline
    P Offline
    PIEBALDconsult
    wrote on last edited by
    #20

    How is that better than what I posted?

    B G 2 Replies Last reply
    0
    • R Robert C Cartaino

      [Message Deleted]

      M Offline
      M Offline
      Mladen Jankovic
      wrote on last edited by
      #21

      Robert.C.Cartaino wrote:

      Writing code that depends on order of evaluation is bad programming practice

      If order of evaluation is not defined by the specification of the language, which is not true for logical operators in C/C++. According to your statement one should not write something like this:

      if( node && node->value )
      node->value->Do();

      Instead you need to have another if for this simple operation even if the previous example is perfectly legal and clean and the desired behavior is guaranteed by the language specification. Well I guess that the only bad programming practice here is that someone introduces unneeded code because he doesn't trust/know language.

      [Genetic Algorithm Library]

      P 1 Reply Last reply
      0
      • M Mladen Jankovic

        Robert.C.Cartaino wrote:

        Writing code that depends on order of evaluation is bad programming practice

        If order of evaluation is not defined by the specification of the language, which is not true for logical operators in C/C++. According to your statement one should not write something like this:

        if( node && node->value )
        node->value->Do();

        Instead you need to have another if for this simple operation even if the previous example is perfectly legal and clean and the desired behavior is guaranteed by the language specification. Well I guess that the only bad programming practice here is that someone introduces unneeded code because he doesn't trust/know language.

        [Genetic Algorithm Library]

        P Offline
        P Offline
        PIEBALDconsult
        wrote on last edited by
        #22

        Indeed. And should we question the order/precedence of the other operators as well? Can we trust 3 + 4 * 5 to return 23? or might it return 35 once in a while? I'm all for adding parentheses for clarity, but I don't get that confused with necessity.

        1 Reply Last reply
        0
        • P PIEBALDconsult

          How is that better than what I posted?

          B Offline
          B Offline
          Ben Fair
          wrote on last edited by
          #23

          Yes, he just inverted the boolean logic and made it worse in my opinion. if(!FlagA || !FlagB) is essentially the same as if(FlagA && FlagB) but I'd rather see the latter and that's how I'd do it in my code.

          Keep It Simple Stupid! (KISS)

          1 Reply Last reply
          0
          • P PIEBALDconsult

            How is that better than what I posted?

            G Offline
            G Offline
            geoffs
            wrote on last edited by
            #24

            It's not. Your code was how I would have done it...

            1 Reply Last reply
            0
            • M Michael Dunn

              You can't make a rule like that because there is no one correct rule that works for every single function you're going to write in your life. Well, you can make the rule, but doing so will be counter-productive. Why create a state machine with local variables in a function (and don't forget to test every possible state!), just to avoid using a perfectly valid language feature?

              --Mike-- Visual C++ MVP :cool: LINKS~! CP SearchBar v3.0 | C++ Forum FAQ I work for Keyser Söze

              U Offline
              U Offline
              User 167261
              wrote on last edited by
              #25

              it all depends on how much coffe i've had for the day...

              do or do not, there is no try

              P 1 Reply Last reply
              0
              • U User 167261

                it all depends on how much coffe i've had for the day...

                do or do not, there is no try

                P Offline
                P Offline
                PIEBALDconsult
                wrote on last edited by
                #26

                Drinking coffee leads to good code. Drinking "energy drinks" leads to poor code.

                1 Reply Last reply
                0
                • G Georgi Atanasov

                  I have a coding rule - avoid "return" somewhere in the middle of a method, try using local variables to compensate instead. Observing this leads to the following (seen in existing code):

                  if(flagA)
                  {
                  if(flagB)
                  {
                  if(flagC)
                  {
                  if(PromtUser())
                  {
                  DoSomething();
                  }
                  else
                  {
                  DoOtherThing();
                  }
                  }
                  else
                  {
                  DoOtherThing();
                  }
                  }
                  else
                  {
                  DoOtherThing();
                  }
                  }
                  else
                  {
                  DoOtherThing();
                  }

                  How I would have written this is:

                  if(flagA)
                  {
                  if(flagB)
                  {
                  if(flagC)
                  {
                  if(PromptUser())
                  {
                  return;
                  }
                  }
                  }
                  }

                  DoOtherThing();

                  I was wondering how you guys feel about it?

                  Thanks, Georgi

                  F Offline
                  F Offline
                  FatBuddha
                  wrote on last edited by
                  #27

                  Assuming that there is more processing going on than this example indicates, I would use a do-while-false loop:

                  do{
                  if(!flagA)break;
                  if(!flagB)break;
                  if(!flagC)break;
                  if(!PromptUser())break;
                  }while(0);

                  DoOtherThing();

                  This is the sort of thing that I routinely do with COM programming where I need to check the success of pretty much every single method call. It means that I don't have a crazy amount of indenting, and it's much cleaner for me or somebody else to understand and modify later. I can highly recommend it.

                  None

                  P 1 Reply Last reply
                  0
                  • G Georgi Atanasov

                    I have a coding rule - avoid "return" somewhere in the middle of a method, try using local variables to compensate instead. Observing this leads to the following (seen in existing code):

                    if(flagA)
                    {
                    if(flagB)
                    {
                    if(flagC)
                    {
                    if(PromtUser())
                    {
                    DoSomething();
                    }
                    else
                    {
                    DoOtherThing();
                    }
                    }
                    else
                    {
                    DoOtherThing();
                    }
                    }
                    else
                    {
                    DoOtherThing();
                    }
                    }
                    else
                    {
                    DoOtherThing();
                    }

                    How I would have written this is:

                    if(flagA)
                    {
                    if(flagB)
                    {
                    if(flagC)
                    {
                    if(PromptUser())
                    {
                    return;
                    }
                    }
                    }
                    }

                    DoOtherThing();

                    I was wondering how you guys feel about it?

                    Thanks, Georgi

                    R Offline
                    R Offline
                    rfidel
                    wrote on last edited by
                    #28

                    Not sure if this made one of the previous replies, but what I found works best, and is easy to follow, is to iteratively step thru what I do not want, making use "else if" statements. After weeding thru all the crap, then what I am left with, is (usually) what I want. if(!flagA) { DoOtherThing(); } else if(!flagB) { DoOtherThing(); } else if(!flagC) { DoOtherThing(); } else if(!PromtUser()) { DoOtherThing(); } else { DoSomething(); }

                    P 1 Reply Last reply
                    0
                    • R rfidel

                      Not sure if this made one of the previous replies, but what I found works best, and is easy to follow, is to iteratively step thru what I do not want, making use "else if" statements. After weeding thru all the crap, then what I am left with, is (usually) what I want. if(!flagA) { DoOtherThing(); } else if(!flagB) { DoOtherThing(); } else if(!flagC) { DoOtherThing(); } else if(!PromtUser()) { DoOtherThing(); } else { DoSomething(); }

                      P Offline
                      P Offline
                      PIEBALDconsult
                      wrote on last edited by
                      #29

                      That's simply the first snippet inverted and made even uglier. It's still a maintenance nightmare.

                      1 Reply Last reply
                      0
                      • F FatBuddha

                        Assuming that there is more processing going on than this example indicates, I would use a do-while-false loop:

                        do{
                        if(!flagA)break;
                        if(!flagB)break;
                        if(!flagC)break;
                        if(!PromptUser())break;
                        }while(0);

                        DoOtherThing();

                        This is the sort of thing that I routinely do with COM programming where I need to check the success of pretty much every single method call. It means that I don't have a crazy amount of indenting, and it's much cleaner for me or somebody else to understand and modify later. I can highly recommend it.

                        None

                        P Offline
                        P Offline
                        PIEBALDconsult
                        wrote on last edited by
                        #30

                        Where's the call to DoSomething? I'm pretty sure that's not applicable to the original post.

                        F 1 Reply Last reply
                        0
                        • P PIEBALDconsult

                          Where's the call to DoSomething? I'm pretty sure that's not applicable to the original post.

                          F Offline
                          F Offline
                          FatBuddha
                          wrote on last edited by
                          #31

                          Doh - I was looking at the second code listing. Assuming that there is lots of other stuff going on between the flag tests, and there is a need for clean-up code (thus don't want to use return), I'd use the same system with a flag:

                          //Figure out what to do...
                          bool doSomething = false;
                          do{
                          if(!flagA)break;
                          if(!flagB)break;
                          if(!flagC)break;
                          if(!PromptUser())break;
                          doSomething = true;
                          }while(0);

                          //...then do it
                          if(doSomething)
                          DoSomething();
                          else
                          DoOtherThing();

                          None

                          P L 2 Replies Last reply
                          0
                          • F FatBuddha

                            Doh - I was looking at the second code listing. Assuming that there is lots of other stuff going on between the flag tests, and there is a need for clean-up code (thus don't want to use return), I'd use the same system with a flag:

                            //Figure out what to do...
                            bool doSomething = false;
                            do{
                            if(!flagA)break;
                            if(!flagB)break;
                            if(!flagC)break;
                            if(!PromptUser())break;
                            doSomething = true;
                            }while(0);

                            //...then do it
                            if(doSomething)
                            DoSomething();
                            else
                            DoOtherThing();

                            None

                            P Offline
                            P Offline
                            PIEBALDconsult
                            wrote on last edited by
                            #32

                            Still looks like a potentially infinite loop.

                            F 1 Reply Last reply
                            0
                            • G Georgi Atanasov

                              I have a coding rule - avoid "return" somewhere in the middle of a method, try using local variables to compensate instead. Observing this leads to the following (seen in existing code):

                              if(flagA)
                              {
                              if(flagB)
                              {
                              if(flagC)
                              {
                              if(PromtUser())
                              {
                              DoSomething();
                              }
                              else
                              {
                              DoOtherThing();
                              }
                              }
                              else
                              {
                              DoOtherThing();
                              }
                              }
                              else
                              {
                              DoOtherThing();
                              }
                              }
                              else
                              {
                              DoOtherThing();
                              }

                              How I would have written this is:

                              if(flagA)
                              {
                              if(flagB)
                              {
                              if(flagC)
                              {
                              if(PromptUser())
                              {
                              return;
                              }
                              }
                              }
                              }

                              DoOtherThing();

                              I was wondering how you guys feel about it?

                              Thanks, Georgi

                              M Offline
                              M Offline
                              Manish K Agarwal
                              wrote on last edited by
                              #33

                              I usualy perfer "goto cleanup" statement (where cleanup is lable inside the function) instead of making code hard to read.

                              Manish Agarwal manish.k.agarwal @ gmail DOT com

                              P T 2 Replies Last reply
                              0
                              • G Georgi Atanasov

                                I have a coding rule - avoid "return" somewhere in the middle of a method, try using local variables to compensate instead. Observing this leads to the following (seen in existing code):

                                if(flagA)
                                {
                                if(flagB)
                                {
                                if(flagC)
                                {
                                if(PromtUser())
                                {
                                DoSomething();
                                }
                                else
                                {
                                DoOtherThing();
                                }
                                }
                                else
                                {
                                DoOtherThing();
                                }
                                }
                                else
                                {
                                DoOtherThing();
                                }
                                }
                                else
                                {
                                DoOtherThing();
                                }

                                How I would have written this is:

                                if(flagA)
                                {
                                if(flagB)
                                {
                                if(flagC)
                                {
                                if(PromptUser())
                                {
                                return;
                                }
                                }
                                }
                                }

                                DoOtherThing();

                                I was wondering how you guys feel about it?

                                Thanks, Georgi

                                M Offline
                                M Offline
                                Marcello Faga
                                wrote on last edited by
                                #34

                                Georgi, I agree with you. "Return in the middle" is an horror! X|

                                **************************** Strong congruence for strong people; with a compatible behaviour. For a semantical way of life.

                                1 Reply Last reply
                                0
                                • P PIEBALDconsult

                                  Still looks like a potentially infinite loop.

                                  F Offline
                                  F Offline
                                  FatBuddha
                                  wrote on last edited by
                                  #35

                                  I can assure you that it isn't! This technique is usually called a do-once block, and commented as such to make it really obvious. Look again at just the 'loop' bit and see if you think that this block of code will still run more than once:

                                  do{//once

                                  }while(0);

                                  What you basically end up with, is a block of code that you can jump to the end of early with a 'break', without having to resort to a 'goto'. That block of code isn't a loop, as it will never run more than once. Get it?

                                  None

                                  P 1 Reply Last reply
                                  0
                                  • F FatBuddha

                                    I can assure you that it isn't! This technique is usually called a do-once block, and commented as such to make it really obvious. Look again at just the 'loop' bit and see if you think that this block of code will still run more than once:

                                    do{//once

                                    }while(0);

                                    What you basically end up with, is a block of code that you can jump to the end of early with a 'break', without having to resort to a 'goto'. That block of code isn't a loop, as it will never run more than once. Get it?

                                    None

                                    P Offline
                                    P Offline
                                    PIEBALDconsult
                                    wrote on last edited by
                                    #36

                                    :doh: Oh, right, that's a 0, my mistake. (Though I still say it looks like an infinite loop.) And that technique is a horror unto itself -- a Weasel-Goto. X|

                                    S 1 Reply Last reply
                                    0
                                    • M Manish K Agarwal

                                      I usualy perfer "goto cleanup" statement (where cleanup is lable inside the function) instead of making code hard to read.

                                      Manish Agarwal manish.k.agarwal @ gmail DOT com

                                      P Offline
                                      P Offline
                                      PIEBALDconsult
                                      wrote on last edited by
                                      #37

                                      ::Shudder::

                                      1 Reply Last reply
                                      0
                                      • R Robert C Cartaino

                                        You forgot to execute DoSomething() in your second example. That aside... I don't necessarily dislike "return in the middle." But I expect early returns to be an error condition (i.e. invalid parameter, resource not obtained, etc) to keep the method from continuing. In your example, the early return seems to be the normal, successful condition and that makes me uncomfortable. So looking at your code samples... Definitely not the first example. If you ever want to add more logic around DoOtherThing(), you've essentially "cut-and-pasted" your code all over the place (a big no-no). There are a lot of conditions where DoOtherThing() would be executed. According to your logic, if each process (A, B, and C) passes, ask the user if they want to DoSomething(). If user says "no" or any of the processes fail, then DoOtherThing(). To make my intentions clear, I would try and write the logic exactly as I would describe it (of course, the variables would be more "English-Like" if I knew their purpose). Maybe something like this:

                                        // assume for the moment, we don't need to DoSomething()
                                        bool DoSomethingNeeded = false;

                                        if (FlagA && FlagB && FlagC)
                                        {
                                        // if all processes passed, ask the user if we need to DoSomething()
                                        DoSomthingNeeded = PromptUser();
                                        }

                                        if (DoSomethingNeeded)
                                        {
                                        DoSomething();
                                        }
                                        else
                                        {
                                        DoOtherThing();
                                        }
                                        return;

                                        J Offline
                                        J Offline
                                        John M Drescher
                                        wrote on last edited by
                                        #38

                                        That is pretty much what I do or just break up the function into smaller parts if there are too many levels of conditionals.

                                        John

                                        1 Reply Last reply
                                        0
                                        • G Georgi Atanasov

                                          I have a coding rule - avoid "return" somewhere in the middle of a method, try using local variables to compensate instead. Observing this leads to the following (seen in existing code):

                                          if(flagA)
                                          {
                                          if(flagB)
                                          {
                                          if(flagC)
                                          {
                                          if(PromtUser())
                                          {
                                          DoSomething();
                                          }
                                          else
                                          {
                                          DoOtherThing();
                                          }
                                          }
                                          else
                                          {
                                          DoOtherThing();
                                          }
                                          }
                                          else
                                          {
                                          DoOtherThing();
                                          }
                                          }
                                          else
                                          {
                                          DoOtherThing();
                                          }

                                          How I would have written this is:

                                          if(flagA)
                                          {
                                          if(flagB)
                                          {
                                          if(flagC)
                                          {
                                          if(PromptUser())
                                          {
                                          return;
                                          }
                                          }
                                          }
                                          }

                                          DoOtherThing();

                                          I was wondering how you guys feel about it?

                                          Thanks, Georgi

                                          R Offline
                                          R Offline
                                          riced
                                          wrote on last edited by
                                          #39

                                          I would tend do follow Michael Jackson's advice: "At this point you might be tempted to introduce a flag. Avoid such Satanic practices." I quote from memory not having read it in the last 10 years. Use of 'flags' to control program flow is often a bad code smell.

                                          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