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. General Programming
  3. C / C++ / MFC
  4. Instead of using nested if-else

Instead of using nested if-else

Scheduled Pinned Locked Moved C / C++ / MFC
11 Posts 10 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.
  • K krishnakumartm

    Hi i have requirement like doing 10 steps to complete task After completion of one only i can enter into another I used nested if- else to do that like if (true) { if (true) { if (true) { return true; } else { } } else { } } else { } is there any better way to handle these type of situation Thanks in Advance

    ---------------------------- KRISHNA KUMAR T M

    H Offline
    H Offline
    Hamid Taebi
    wrote on last edited by
    #2

    Yes switch(i) { case 0: break; case 1: break; default: break; }

    C 1 Reply Last reply
    0
    • H Hamid Taebi

      Yes switch(i) { case 0: break; case 1: break; default: break; }

      C Offline
      C Offline
      Code o mat
      wrote on last edited by
      #3

      How about:

      if (expression1 &&
      expression2 &&
      expression3 &&
      expression4 &&
      ...) ... //success
      else //failure...

      or an uglier aproach:

      try {
      if (!expression1) throw 1;
      if (!expression2) throw 2;
      if (!expression3) throw 3;
      ...
      } catch (int where)
      {
      //Do whatever here, "where" will even show you where the whole thing failed
      }

      > The problem with computers is that they do what you tell them to do and not what you want them to do. <

      S 1 Reply Last reply
      0
      • K krishnakumartm

        Hi i have requirement like doing 10 steps to complete task After completion of one only i can enter into another I used nested if- else to do that like if (true) { if (true) { if (true) { return true; } else { } } else { } } else { } is there any better way to handle these type of situation Thanks in Advance

        ---------------------------- KRISHNA KUMAR T M

        C Offline
        C Offline
        CPallini
        wrote on last edited by
        #4

        Usually this can be handled (as already suggested) with try-catch blocks or (using plain C) with the (in)famous goto. You may also schedule a set of operation to be invoked inside a loop (for instance with an array of function pointers) and use break to interrupt the iteration whenever needed (i.e. on any operation failure). :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
        [My articles]

        1 Reply Last reply
        0
        • C Code o mat

          How about:

          if (expression1 &&
          expression2 &&
          expression3 &&
          expression4 &&
          ...) ... //success
          else //failure...

          or an uglier aproach:

          try {
          if (!expression1) throw 1;
          if (!expression2) throw 2;
          if (!expression3) throw 3;
          ...
          } catch (int where)
          {
          //Do whatever here, "where" will even show you where the whole thing failed
          }

          > The problem with computers is that they do what you tell them to do and not what you want them to do. <

          S Offline
          S Offline
          ssclaire
          wrote on last edited by
          #5

          The argument is "are guard clauses in methods okay?" And how do you handle resource cleanup if one of the guard clauses fail? I haven't seen a convincing consensus either way. A specific example: Let's say you have 10 resources to allocate (like opening files, networks, etc) -- for brevity here, let's just use four resources. All resources have to be allocated for the method to continue. So what we are trying to avoid is something like this (yuck):

          isMethodSuccessful = false; // assume this isn't going to work
          resource1 = OpenMyFile(myFile);
          if (resource1 == SUCCESS)
          {
          resource2 = OpenSomeNetworkConnection(networkID)
          if (resource2 == OKAY)
          {
          resource3 = CreateNewFile(outputFile);
          if (resource3 == SUCCESS)
          {
          resource4 = ConnectToSomething(mySomething);
          if (resource4)
          {
          //
          // Do all my logic here
          //
          isMethodSuccessful = true; // return success
          }
          else
          {
          DeleteFile(resource3); // do cleanup
          CloseNetwork(resource2);
          CloseFile(resource1);
          }
          }
          else
          {
          CloseNetwork(resource2); // do cleanup
          CloseFile(resource1);
          }
          }
          else
          {
          CloseFile(resource1); // do cleanup
          }

           return (isMethodSuccessful);
          

          }

          Guard clauses will convert that mess into something like this:

          resource1 = OpenMyFile(myFile);
          if (resource1 != SUCCESS)
          {
          return failure;
          }

          resource2 = OpenSomeNetworkConnection(networkID)
          if (resource2 != OKAY)
          {
          CloseFile(resource1); // do cleanup
          return failure;
          }

          resource3 = CreateNewFile(outputFile);
          if (resource3 != SUCCESS)
          {
          CloseNetwork(resource2); // do cleanup
          CloseFile(resource1);
          return failure;
          }

          resource4 = ConnectToSomething(mySomething);
          if (!resource4)
          {
          DeleteFile(resource3); // do cleanup
          CloseNetwork(resource2);
          CloseFile(resource1);
          return failure;
          }

          //
          // Put all your logic here
          //

          return (success);

          ...which is far from ideal (i.e. more yuck). So what's the best code logic in this situation?

          C N T 3 Replies Last reply
          0
          • S ssclaire

            The argument is "are guard clauses in methods okay?" And how do you handle resource cleanup if one of the guard clauses fail? I haven't seen a convincing consensus either way. A specific example: Let's say you have 10 resources to allocate (like opening files, networks, etc) -- for brevity here, let's just use four resources. All resources have to be allocated for the method to continue. So what we are trying to avoid is something like this (yuck):

            isMethodSuccessful = false; // assume this isn't going to work
            resource1 = OpenMyFile(myFile);
            if (resource1 == SUCCESS)
            {
            resource2 = OpenSomeNetworkConnection(networkID)
            if (resource2 == OKAY)
            {
            resource3 = CreateNewFile(outputFile);
            if (resource3 == SUCCESS)
            {
            resource4 = ConnectToSomething(mySomething);
            if (resource4)
            {
            //
            // Do all my logic here
            //
            isMethodSuccessful = true; // return success
            }
            else
            {
            DeleteFile(resource3); // do cleanup
            CloseNetwork(resource2);
            CloseFile(resource1);
            }
            }
            else
            {
            CloseNetwork(resource2); // do cleanup
            CloseFile(resource1);
            }
            }
            else
            {
            CloseFile(resource1); // do cleanup
            }

             return (isMethodSuccessful);
            

            }

            Guard clauses will convert that mess into something like this:

            resource1 = OpenMyFile(myFile);
            if (resource1 != SUCCESS)
            {
            return failure;
            }

            resource2 = OpenSomeNetworkConnection(networkID)
            if (resource2 != OKAY)
            {
            CloseFile(resource1); // do cleanup
            return failure;
            }

            resource3 = CreateNewFile(outputFile);
            if (resource3 != SUCCESS)
            {
            CloseNetwork(resource2); // do cleanup
            CloseFile(resource1);
            return failure;
            }

            resource4 = ConnectToSomething(mySomething);
            if (!resource4)
            {
            DeleteFile(resource3); // do cleanup
            CloseNetwork(resource2);
            CloseFile(resource1);
            return failure;
            }

            //
            // Put all your logic here
            //

            return (success);

            ...which is far from ideal (i.e. more yuck). So what's the best code logic in this situation?

            C Offline
            C Offline
            CPallini
            wrote on last edited by
            #6

            For instance, the C language goto statement allows to handle well the above scenario. :)

            If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
            This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
            [My articles]

            1 Reply Last reply
            0
            • S ssclaire

              The argument is "are guard clauses in methods okay?" And how do you handle resource cleanup if one of the guard clauses fail? I haven't seen a convincing consensus either way. A specific example: Let's say you have 10 resources to allocate (like opening files, networks, etc) -- for brevity here, let's just use four resources. All resources have to be allocated for the method to continue. So what we are trying to avoid is something like this (yuck):

              isMethodSuccessful = false; // assume this isn't going to work
              resource1 = OpenMyFile(myFile);
              if (resource1 == SUCCESS)
              {
              resource2 = OpenSomeNetworkConnection(networkID)
              if (resource2 == OKAY)
              {
              resource3 = CreateNewFile(outputFile);
              if (resource3 == SUCCESS)
              {
              resource4 = ConnectToSomething(mySomething);
              if (resource4)
              {
              //
              // Do all my logic here
              //
              isMethodSuccessful = true; // return success
              }
              else
              {
              DeleteFile(resource3); // do cleanup
              CloseNetwork(resource2);
              CloseFile(resource1);
              }
              }
              else
              {
              CloseNetwork(resource2); // do cleanup
              CloseFile(resource1);
              }
              }
              else
              {
              CloseFile(resource1); // do cleanup
              }

               return (isMethodSuccessful);
              

              }

              Guard clauses will convert that mess into something like this:

              resource1 = OpenMyFile(myFile);
              if (resource1 != SUCCESS)
              {
              return failure;
              }

              resource2 = OpenSomeNetworkConnection(networkID)
              if (resource2 != OKAY)
              {
              CloseFile(resource1); // do cleanup
              return failure;
              }

              resource3 = CreateNewFile(outputFile);
              if (resource3 != SUCCESS)
              {
              CloseNetwork(resource2); // do cleanup
              CloseFile(resource1);
              return failure;
              }

              resource4 = ConnectToSomething(mySomething);
              if (!resource4)
              {
              DeleteFile(resource3); // do cleanup
              CloseNetwork(resource2);
              CloseFile(resource1);
              return failure;
              }

              //
              // Put all your logic here
              //

              return (success);

              ...which is far from ideal (i.e. more yuck). So what's the best code logic in this situation?

              N Offline
              N Offline
              Nemanja Trifunovic
              wrote on last edited by
              #7

              Actually, your "yuck" example is much better than the "more yack" one. The former is just yacky, and the later is dangerous (think introducing changes to the function and remembering to copy/paste all the resource cleanup). The only robust and non-yacky way to handle this situation is use of The RAII programming idiom[^] In this case, the destructors will make sure that all your resources are freed at the end of the scope - even if you throw an exception.

              Programming Blog utf8-cpp

              1 Reply Last reply
              0
              • K krishnakumartm

                Hi i have requirement like doing 10 steps to complete task After completion of one only i can enter into another I used nested if- else to do that like if (true) { if (true) { if (true) { return true; } else { } } else { } } else { } is there any better way to handle these type of situation Thanks in Advance

                ---------------------------- KRISHNA KUMAR T M

                D Offline
                D Offline
                David Crow
                wrote on last edited by
                #8

                krishnakumartm wrote:

                is there any better way to handle these type of situation

                Yes, like:

                if (ret)
                ret = foo1();

                if (ret)
                ret = foo2();

                if (ret)
                ret = foo3();

                if (ret)
                ret = foo4();

                If any of the function calls fail, none of the remaining ones will execute.

                "Love people and use things, not love things and use people." - Unknown

                "The brick walls are there for a reason...to stop the people who don't want it badly enough." - Randy Pausch

                1 Reply Last reply
                0
                • K krishnakumartm

                  Hi i have requirement like doing 10 steps to complete task After completion of one only i can enter into another I used nested if- else to do that like if (true) { if (true) { if (true) { return true; } else { } } else { } } else { } is there any better way to handle these type of situation Thanks in Advance

                  ---------------------------- KRISHNA KUMAR T M

                  B Offline
                  B Offline
                  bob16972
                  wrote on last edited by
                  #9

                  Tons of COM examples and winsock examples use this approach in methods which would normally result in deep nested branch statements... void CSomeClass::SomeMethod(void) { if (FALSE) { return; } // got here 1 if (FALSE) { return; } // got here 2 if (FALSE) { return; } // got here 3 // ... }

                  1 Reply Last reply
                  0
                  • K krishnakumartm

                    Hi i have requirement like doing 10 steps to complete task After completion of one only i can enter into another I used nested if- else to do that like if (true) { if (true) { if (true) { return true; } else { } } else { } } else { } is there any better way to handle these type of situation Thanks in Advance

                    ---------------------------- KRISHNA KUMAR T M

                    S Offline
                    S Offline
                    sheshidar
                    wrote on last edited by
                    #10

                    if (true)
                    {
                    if (true)
                    {
                    if (true)
                    {
                    return true;
                    }
                    else
                    {
                    }
                    }
                    else
                    {
                    }
                    }
                    else
                    {
                    }

                    Do you need to do something in each else block? if yes than follow the same, else you can use

                    if((condition1)&&(condition2)&&(condition3))
                    return true;
                    else
                    return false;

                    1 Reply Last reply
                    0
                    • S ssclaire

                      The argument is "are guard clauses in methods okay?" And how do you handle resource cleanup if one of the guard clauses fail? I haven't seen a convincing consensus either way. A specific example: Let's say you have 10 resources to allocate (like opening files, networks, etc) -- for brevity here, let's just use four resources. All resources have to be allocated for the method to continue. So what we are trying to avoid is something like this (yuck):

                      isMethodSuccessful = false; // assume this isn't going to work
                      resource1 = OpenMyFile(myFile);
                      if (resource1 == SUCCESS)
                      {
                      resource2 = OpenSomeNetworkConnection(networkID)
                      if (resource2 == OKAY)
                      {
                      resource3 = CreateNewFile(outputFile);
                      if (resource3 == SUCCESS)
                      {
                      resource4 = ConnectToSomething(mySomething);
                      if (resource4)
                      {
                      //
                      // Do all my logic here
                      //
                      isMethodSuccessful = true; // return success
                      }
                      else
                      {
                      DeleteFile(resource3); // do cleanup
                      CloseNetwork(resource2);
                      CloseFile(resource1);
                      }
                      }
                      else
                      {
                      CloseNetwork(resource2); // do cleanup
                      CloseFile(resource1);
                      }
                      }
                      else
                      {
                      CloseFile(resource1); // do cleanup
                      }

                       return (isMethodSuccessful);
                      

                      }

                      Guard clauses will convert that mess into something like this:

                      resource1 = OpenMyFile(myFile);
                      if (resource1 != SUCCESS)
                      {
                      return failure;
                      }

                      resource2 = OpenSomeNetworkConnection(networkID)
                      if (resource2 != OKAY)
                      {
                      CloseFile(resource1); // do cleanup
                      return failure;
                      }

                      resource3 = CreateNewFile(outputFile);
                      if (resource3 != SUCCESS)
                      {
                      CloseNetwork(resource2); // do cleanup
                      CloseFile(resource1);
                      return failure;
                      }

                      resource4 = ConnectToSomething(mySomething);
                      if (!resource4)
                      {
                      DeleteFile(resource3); // do cleanup
                      CloseNetwork(resource2);
                      CloseFile(resource1);
                      return failure;
                      }

                      //
                      // Put all your logic here
                      //

                      return (success);

                      ...which is far from ideal (i.e. more yuck). So what's the best code logic in this situation?

                      T Offline
                      T Offline
                      Timothy Baldwin
                      wrote on last edited by
                      #11

                      ssclaire wrote:

                      And how do you handle resource cleanup if one of the guard clauses fail?

                      Use RAII, see http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization[^].

                      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