Assuming I have this pseudo-code:
bool conditionA = executeStepA();
if (conditionA){
bool conditionB = executeStepB();
if (conditionB){
bool conditionC = executeStepC();
if (conditionC){
...
}
}
}
executeThisFunctionInAnyCase();
Functions executeStepX
should be executed if and only if the previous succeed.
In any case, the executeThisFunctionInAnyCase
function should be called at the end.
I'm a newbie in programming, so sorry for the very basic question: is there a way (in C/C++ for example) to avoid that long if
chain producing that sort of "pyramid of code", at the expense of the code legibility?
I know that if we could skip the executeThisFunctionInAnyCase
function call, the code could be simplified as:
bool conditionA = executeStepA();
if (!conditionA) return;
bool conditionB = executeStepB();
if (!conditionB) return;
bool conditionC = executeStepC();
if (!conditionC) return;
But the constraint is the executeThisFunctionInAnyCase
function call.
Could the break
statement be used in some way?
Old school C programmers use
goto
in this case. It is the one usage ofgoto
that's actually encouraged by the Linux styleguide, it's called the centralized function exit:Some people work around using
goto
by wrapping the body into a loop and breaking from it, but effectively both approaches do the same thing. Thegoto
approach is better if you need some other cleanup only ifexecuteStepA()
was successfull:With the loop approach you would end up with two levels of loops in that case.
If you dislike
goto
and dislikedo { } while (0);
loops and like to use C++ you can also use a temporary lambda to have the same effect.The chains of IF/ELSE in your code is not the language issue, but the design of your program. If you're able to re-factor or re-write your program I'd like to suggest that you look in Design Patterns (http://sourcemaking.com/design_patterns) to find a better solution.
Usually, when you see a lot of IF's & else's in your code , it is an opportunity to implement the Strategy Design Pattern (http://sourcemaking.com/design_patterns/strategy/c-sharp-dot-net) or maybe a combination of other patterns.
I'm sure there're alternatives to write a long list of if/else , but I doubt they will change anything except that the chain will look pretty to you (However, the beauty is in the eye of the beholder still applies to code too:-) ) . You should be concerned about things like (in 6 months when I have a new condition and I don't remember anything about this code , will I be able to add it easily? Or what if the chain changes, how quickly and error-free will I be implement it)
For C++11 and beyond, a nice approach might be to implement a scope exit system similar to D's scope(exit) mechanism.
One possible way to implement it is using C++11 lambdas and some helper macros:
This will allow you to return early from the function and ensure whatever cleanup code you define is always executed upon scope exit:
The macros are really just decoration.
MakeScopeExit()
can be used directly.Why is nobody giving the simplest solution ? :D
If all your functions have the same signature then you can do it this way (for C language):
For a clean C++ solution, you should create an interface class that contains an execute method and wraps your steps in objects.
Then, the solution above will look like this:
This looks like a state machine, which is handy because you can easily implement it with a state-pattern.
In Java it would look something like this:
An implementation would work as follows:
And so on. Then you can substitute the big if condition with: