Avoiding deeply-nested if…else chains

Sometimes you get code that looks like this:

if (check1()) {
    // Do something...
    if (check2()) {
        // Do more...
        if (check3()) {
            // And more...
        }
    }
}

The code is rapidly moving away from the left margin, and becoming difficult to read. You can’t just combine the checks with && because something is being done between them.

I think the best thing to do in this case is to put the code into a separate function, negate the checks, and use a return when they fail. This has the advantage that you can return a different value for each check failure, so it becomes much easier to test.

int f()
{
    if (!check1()) {
        return CHECK1_FAILED;
    }
    // Do something...
    if (!check2()) {
        return CHECK2_FAILED;
    }
    // Do more...
    if (!check3()) {
        return CHECK3_FAILED;
    }
    // And more...
    return SUCCEEDED;
}