Need help for optimising nested ifs-help me plz panic situation!!!

Discussion in 'C Programming' started by s.subbarayan, Sep 11, 2004.

  1. s.subbarayan

    s.subbarayan Guest

    Dear all,
    Whats the common practice followed generally in the industry to
    avoid large number of "nested ifs" in a C code?I am currently working
    with a code which has a tremendous nests (in the order of around 25 or
    more!)and feeling really tough to maintain it.Also the code is for a
    application which has lots of dependecies.
    My application demands that the current output is dependent on
    previous output.Like this in my application I have now reached 25
    dependencies in nests.
    Need valuable suggestions to overcome this and to make my code easily
    maintainable.
    expecting your replys and advanced thanks for the same,
    Regards,
    s.subbarayan
     
    s.subbarayan, Sep 11, 2004
    #1
    1. Advertisements

  2. s.subbarayan

    Malcolm Guest

    Most programs will have a huge depth of nested conditionals, but not in the
    same function. Each function should do one clearly defined thing, whether
    that is high level (steer spaceship to Mars), medium level (calculate
    distance from destination), or low level (square root).

    You will probably find that the conditionals boil down to a few tests. For
    instance

    if( employee.status == salesman)
    {
    if(sales > target)
    dobonus();
    }
    else if employee.status == director
    {
    if(shareprice > target)
    dobonus();
    }

    This could be consolidated

    if( bonuspayable(&employee))
    dobonus();

    with the logic put into the bonuspayable() function. This is more readable
    and may be easier to maintain.
    This is a very important relationship. In C, one of the main tips is to
    avoid gotchas like #defining BOOL, or a POINT structure. The other tip is to
    try to design in a strict hierarchy, with low-level functions, grouped by
    type, in different files from high-level functions. Avoid mutual
    dependencies between files.
     
    Malcolm, Sep 11, 2004
    #2
    1. Advertisements

  3. s.subbarayan

    Ed Morton Guest

    If it's appropriate for all that code to be in one function, you could
    structure it as a FSM/Decision Tree, e.g. instead of:

    foo() {
    int ret;
    ret = getRsrc1();
    if (ret == 1) {
    ret = getRsrc2();
    if (ret == 1) {
    ret = doStuff();
    if (ret == 1) {
    printf("Success!\n");
    } else {
    printf("Failed to do stuff.\n");
    }
    relRsrc2();
    relRsrc1();
    } else {
    printf("Failed to get resource 2.\n");
    relRsrc1();
    }
    } else {
    printf("Failed to get resource 1.\n");
    }
    }

    you could write something like this:

    foo() {
    enum { INIT, GOT_RSRC1, GOT_RSRC2, DONE} state = INIT;
    int ret;
    while (state != DONE) {
    switch(state) {
    case INIT:
    ret = getRsrc1();
    if (ret == 1) {
    state = GOT_RSRC1;
    } else {
    printf("Failed to get resource 1.\n");
    state = DONE;
    }
    break;
    case GOT_RSRC1:
    ret = getRsrc2();
    if (ret == 1) {
    state = GOT_RSRC2;
    } else {
    printf("Failed to get resource 2.\n");
    relRsrc1();
    state = DONE;
    }
    break;
    case GOT_RSRC2:
    ret = doStuff();
    if (ret == 1) {
    printf("Success!\n");
    } else {
    printf("Failed to do stuff.\n");
    }
    relRsrc2();
    relRsrc1();
    state = DONE;
    break;
    case DONE: /* fall through */
    default:
    printf("Should never get here....\n");
    break;
    }
    }
    }

    You probably wouldn't bother to do that for the trivial code shown here,
    but hopefully you can see that the above structure can turn your 25-deep
    nested if statements into just a while and a switch. Also, the above
    example couldv'e been written as just a sequence of "if" tests on state
    without the while/switch since it's a sequence of states, but in the
    general case there may be several possible next states from the current
    state, and for that you need the while/switch or similair constructs.

    Ed.
     
    Ed Morton, Sep 11, 2004
    #3
  4. Large series of nested ifs are often a result of a particularly
    unmaintainable method of error-checking:

    <allocate resource>
    if (succeeded) {
    <allocate resource 2>
    if (succeeded) {
    ...
    <free resource 2>
    }
    <free resource>
    }

    If the number of resources is large (say, 3 or more) a better way to
    handle this is using goto:

    {
    <allocate resource>
    if (!succeeded) goto end;
    <allocate resource 2>
    if (!succeeded) goto dealloc_1;
    <allocate resource 3>
    if (!succeeded) goto dealloc_2;
    .....
    dealloc_2: <free resource 2>
    dealloc_1: <free resource 1>
    end: ;
    }

    In C++ you could simply return on failure and destructors would effect
    the same deallocation sequence.
     
    Derrick Coetzee, Sep 11, 2004
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.