Click here to Skip to main content
15,892,072 members

Response to: escaping a large function

Revision 3
Your problem can be solved in several ways. The first you should notice that your coding style isn't alright, you are probably writing Spaghetti code[^]. That's not a problem especially if you are a beginner because I'm pretty sure everyone starts with spaghetti. The problem is if you keep that style because some people tend to do so either becuase of stupidity or lazyness. Spaghetti is usually a result of bad code design that is the result of bad or no Separation of concerns[^]. You are trying to implement of lot of things (or everything) inside one function instead of breaking that stuff into several functions or classes. In general, if your function spans vertically more than what you can read on your monitor on "one page" then your code is spaghetti and needs splitting into several functions or classes. The solution to the problem of breaking out more than one loop is missing from C/C++, in some other languages its present, for example in java. If you take a look at the following page and search for the "search:" label on it then you will see a java snippet that breaks out from 2 loops: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html[^]. However in C/C++ you can not do that but you can achieve similar behaviour. One of them is using an exception what I don't recommend in C++ and is not available in C. The other solution is putting the whole spaghetti code with all loops into a separated function and then instead of breaking out from the loop you return from the function call where you want to break from several loops. This way your program doesn't exit, just returns from a function. Putting things to a separate function call is a good solution to a lot of problems in C.

Example:
C++
// an ugly spaghetti solution of breaking out from 2 loops but sometimes it does the job
bool stop = false;
for (int i=0; i<5; ++i)
{
    for (int j=0; j<5; ++j)
    {
        printf("%d, %d\n", i, j);
        if (i==3 && j==3)
        {
            stop = true;
            break;
        }
        if (stop)
            break;
    }
}

// the function + return solution
void perform_loops()
{
    for (int i=0; i<5; ++i)
    {
        for (int j=0; j<5; ++j)
        {
            printf("%d, %d\n", i, j);
            if (i==3 && j==3)
                return;
        }
    }
}

// calling the function
perform_loops();


If you have a big ugly function with a lot of local variables with long code then its the best to do the following as a first step of refactorization:
1. Create an empty class and put the local variables of the function into the empty class as member variables.
2. Put the whole original function code into the class so that it uses the member variables of the class instead of local variables.
3. Split the method in the class into several methods, its quite easy since every method of the class can access every member variable of the class.
4. Now you have several methods in the class that depend on each other via member variables (variable initialization order, call order) so your next task is to make that dependency cleaner - this is much easier to solve than the original problem you started from (spaghetty/monster func). During this you might find out that some methods use only some of the member variables of the class so you can split those member variables into another class with all the methods that use those member variables and then you can use the second class from the first one.

Now that you have your new class (or classes) your original ugly function looks like the following:
C++
int previously_ugly_func(params)
{
    MyNewPrettyClass c;
    return c.DoWork(params);
}

Instead of calling the original ugly func you can directly use the new class that solves the same problem you original ugly func solved.
Posted 4-Nov-12 2:53am by pasztorpisti.
Tags: