How to avoid "if" chains? - c++

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?

You can use an && (logic AND):
if (executeStepA() && executeStepB() && executeStepC()){
...
}
executeThisFunctionInAnyCase();
this will satisfy both of your requirements:
executeStep<X>() should evaluate only if the previous one succeeded (this is called short circuit evaluation)
executeThisFunctionInAnyCase() will be executed in any case

Just use an additional function to get your second version to work:
void foo()
{
bool conditionA = executeStepA();
if (!conditionA) return;
bool conditionB = executeStepB();
if (!conditionB) return;
bool conditionC = executeStepC();
if (!conditionC) return;
}
void bar()
{
foo();
executeThisFunctionInAnyCase();
}
Using either deeply nested ifs (your first variant) or the desire to break out of "part of a function" usually means you do need an extra function.

Old school C programmers use goto in this case. It is the one usage of goto that's actually encouraged by the Linux styleguide, it's called the centralized function exit:
int foo() {
int result = /*some error code*/;
if(!executeStepA()) goto cleanup;
if(!executeStepB()) goto cleanup;
if(!executeStepC()) goto cleanup;
result = 0;
cleanup:
executeThisFunctionInAnyCase();
return result;
}
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. The goto approach is better if you need some other cleanup only if executeStepA() was successfull:
int foo() {
int result = /*some error code*/;
if(!executeStepA()) goto cleanupPart;
if(!executeStepB()) goto cleanup;
if(!executeStepC()) goto cleanup;
result = 0;
cleanup:
innerCleanup();
cleanupPart:
executeThisFunctionInAnyCase();
return result;
}
With the loop approach you would end up with two levels of loops in that case.

This is a common situation and there are many common ways to deal with it. Here's my attempt at a canonical answer. Please comment if I missed anything and I'll keep this post up to date.
This is an Arrow
What you are discussing is known as the arrow anti-pattern. It is called an arrow because the chain of nested ifs form code blocks that expand farther and farther to the right and then back to the left, forming a visual arrow that "points" to the right side of the code editor pane.
Flatten the Arrow with the Guard
Some common ways of avoiding the Arrow are discussed here. The most common method is to use a guard pattern, in which the code handles the exception flows first and then handles the basic flow, e.g. instead of
if (ok)
{
DoSomething();
}
else
{
_log.Error("oops");
return;
}
... you'd use....
if (!ok)
{
_log.Error("oops");
return;
}
DoSomething(); //notice how this is already farther to the left than the example above
When there is a long series of guards this flattens the code considerably as all the guards appear all the way to the left and your ifs are not nested. In addition, you are visually pairing the logic condition with its associated error, which makes it far easier to tell what is going on:
Arrow:
ok = DoSomething1();
if (ok)
{
ok = DoSomething2();
if (ok)
{
ok = DoSomething3();
if (!ok)
{
_log.Error("oops"); //Tip of the Arrow
return;
}
}
else
{
_log.Error("oops");
return;
}
}
else
{
_log.Error("oops");
return;
}
Guard:
ok = DoSomething1();
if (!ok)
{
_log.Error("oops");
return;
}
ok = DoSomething2();
if (!ok)
{
_log.Error("oops");
return;
}
ok = DoSomething3();
if (!ok)
{
_log.Error("oops");
return;
}
ok = DoSomething4();
if (!ok)
{
_log.Error("oops");
return;
}
This is objectively and quantifiably easier to read because
The { and } characters for a given logic block are closer together
The amount of mental context needed to understand a particular line is smaller
The entirety of logic associated with an if condition is more likely to be on one page
The need for the coder to scroll the page/eye track is greatly lessened
How to add common code at the end
The problem with the guard pattern is that it relies on what is called "opportunistic return" or "opportunistic exit." In other words, it breaks the pattern that each and every function should have exactly one point of exit. This is a problem for two reasons:
It rubs some people the wrong way, e.g. people who learned to code on Pascal have learned that one function = one exit point.
It does not provide a section of code that executes upon exit no matter what, which is the subject at hand.
Below I've provided some options for working around this limitation either by using language features or by avoiding the problem altogether.
Option 1. You can't do this: use finally
Unfortunately, as a c++ developer, you can't do this. But this is the number one answer for languages that contain a finally keyword, since this is exactly what it is for.
try
{
if (!ok)
{
_log.Error("oops");
return;
}
DoSomething(); //notice how this is already farther to the left than the example above
}
finally
{
DoSomethingNoMatterWhat();
}
Option 2. Avoid the issue: Restructure your functions
You can avoid the problem by breaking the code into two functions. This solution has the benefit of working for any language, and additionally it can reduce cyclomatic complexity, which is a proven way to reduce your defect rate, and improves the specificity of any automated unit tests.
Here's an example:
void OuterFunction()
{
DoSomethingIfPossible();
DoSomethingNoMatterWhat();
}
void DoSomethingIfPossible()
{
if (!ok)
{
_log.Error("Oops");
return;
}
DoSomething();
}
Option 3. Language trick: Use a fake loop
Another common trick I see is using while(true) and break, as shown in the other answers.
while(true)
{
if (!ok) break;
DoSomething();
break; //important
}
DoSomethingNoMatterWhat();
While this is less "honest" than using goto, it is less prone to being messed up when refactoring, as it clearly marks the boundaries of logic scope. A naive coder who cuts and pastes your labels or your goto statements can cause major problems! (And frankly the pattern is so common now I think it clearly communicates the intent, and is therefore not "dishonest" at all).
There are other variants of this options. For example, one could use switch instead of while. Any language construct with a break keyword would probably work.
Option 4. Leverage the object life cycle
One other approach leverages the object life cycle. Use a context object to carry around your parameters (something which our naive example suspiciously lacks) and dispose of it when you're done.
class MyContext
{
~MyContext()
{
DoSomethingNoMatterWhat();
}
}
void MainMethod()
{
MyContext myContext;
ok = DoSomething(myContext);
if (!ok)
{
_log.Error("Oops");
return;
}
ok = DoSomethingElse(myContext);
if (!ok)
{
_log.Error("Oops");
return;
}
ok = DoSomethingMore(myContext);
if (!ok)
{
_log.Error("Oops");
}
//DoSomethingNoMatterWhat will be called when myContext goes out of scope
}
Note: Be sure you understand the object life cycle of your language of choice. You need some sort of deterministic garbage collection for this to work, i.e. you have to know when the destructor will be called. In some languages you will need to use Dispose instead of a destructor.
Option 4.1. Leverage the object life cycle (wrapper pattern)
If you're going to use an object-oriented approach, may as well do it right. This option uses a class to "wrap" the resources that require cleanup, as well as its other operations.
class MyWrapper
{
bool DoSomething() {...};
bool DoSomethingElse() {...}
void ~MyWapper()
{
DoSomethingNoMatterWhat();
}
}
void MainMethod()
{
bool ok = myWrapper.DoSomething();
if (!ok)
_log.Error("Oops");
return;
}
ok = myWrapper.DoSomethingElse();
if (!ok)
_log.Error("Oops");
return;
}
}
//DoSomethingNoMatterWhat will be called when myWrapper is destroyed
Again, be sure you understand your object life cycle.
Option 5. Language trick: Use short-circuit evaluation
Another technique is to take advantage of short-circuit evaluation.
if (DoSomething1() && DoSomething2() && DoSomething3())
{
DoSomething4();
}
DoSomethingNoMatterWhat();
This solution takes advantage of the way the && operator works. When the left hand side of && evaluates to false, the right hand side is never evaluated.
This trick is most useful when compact code is required and when the code is not likely to see much maintenance, e.g you are implementing a well-known algorithm. For more general coding the structure of this code is too brittle; even a minor change to the logic could trigger a total rewrite.

Just do
if( executeStepA() && executeStepB() && executeStepC() )
{
// ...
}
executeThisFunctionInAnyCase();
It's that simple.
Due to three edits that each has fundamentally changed the question (four if one counts the revision back to version #1), I include the code example I'm answering to:
bool conditionA = executeStepA();
if (conditionA){
bool conditionB = executeStepB();
if (conditionB){
bool conditionC = executeStepC();
if (conditionC){
...
}
}
}
executeThisFunctionInAnyCase();

There is actually a way to defer actions in C++: making use of an object's destructor.
Assuming that you have access to C++11:
class Defer {
public:
Defer(std::function<void()> f): f_(std::move(f)) {}
~Defer() { if (f_) { f_(); } }
void cancel() { f_ = std::function<void()>(); }
private:
Defer(Defer const&) = delete;
Defer& operator=(Defer const&) = delete;
std::function<void()> f_;
}; // class Defer
And then using that utility:
int foo() {
Defer const defer{&executeThisFunctionInAnyCase}; // or a lambda
// ...
if (!executeA()) { return 1; }
// ...
if (!executeB()) { return 2; }
// ...
if (!executeC()) { return 3; }
// ...
return 4;
} // foo

There's a nice technique which doesn't need an additional wrapper function with the return statements (the method prescribed by Itjax). It makes use of a do while(0) pseudo-loop. The while (0) ensures that it is actually not a loop but executed only once. However, the loop syntax allows the use of the break statement.
void foo()
{
// ...
do {
if (!executeStepA())
break;
if (!executeStepB())
break;
if (!executeStepC())
break;
}
while (0);
// ...
}

You could also do this:
bool isOk = true;
std::vector<bool (*)(void)> funcs; //vector of function ptr
funcs.push_back(&executeStepA);
funcs.push_back(&executeStepB);
funcs.push_back(&executeStepC);
//...
//this will stop at the first false return
for (auto it = funcs.begin(); it != funcs.end() && isOk; ++it)
isOk = (*it)();
if (isOk)
//doSomeStuff
executeThisFunctionInAnyCase();
This way you have a minimal linear growth size, +1 line per call, and it's easily maintenable.
EDIT: (Thanks #Unda) Not a big fan because you loose visibility IMO :
bool isOk = true;
auto funcs { //using c++11 initializer_list
&executeStepA,
&executeStepB,
&executeStepC
};
for (auto it = funcs.begin(); it != funcs.end() && isOk; ++it)
isOk = (*it)();
if (isOk)
//doSomeStuff
executeThisFunctionInAnyCase();

Would this work? I think this is equivalent with your code.
bool condition = true; // using only one boolean variable
if (condition) condition = executeStepA();
if (condition) condition = executeStepB();
if (condition) condition = executeStepC();
...
executeThisFunctionInAnyCase();

Assuming the desired code is as I currently see it:
bool conditionA = executeStepA();
if (conditionA){
bool conditionB = executeStepB();
if (conditionB){
bool conditionC = executeStepC();
if (conditionC){
...
}
}
}
executeThisFunctionInAnyCase();
I would say that the correct approach, in that it's the simplest to read and easiest to maintain, would have fewer levels of indentation, which is (currently) the stated purpose of the question.
// Pre-declare the variables for the conditions
bool conditionA = false;
bool conditionB = false;
bool conditionC = false;
// Execute each step only if the pre-conditions are met
conditionA = executeStepA();
if (conditionA)
conditionB = executeStepB();
if (conditionB)
conditionC = executeStepC();
if (conditionC) {
...
}
// Unconditionally execute the 'cleanup' part.
executeThisFunctionInAnyCase();
This avoids any need for gotos, exceptions, dummy while loops, or other difficult constructs and simply gets on with the simple job at hand.

Could break statement be used in some way?
Maybe not the best solution but you can put your statements in a do .. while (0) loop and use break statements instead of return.

You could put all the if conditions, formatted as you want it in a function of their own, the on return execute the executeThisFunctionInAnyCase() function.
From the base example in the OP, the condition testing and execution can be split off as such;
void InitialSteps()
{
bool conditionA = executeStepA();
if (!conditionA)
return;
bool conditionB = executeStepB();
if (!conditionB)
return;
bool conditionC = executeStepC();
if (!conditionC)
return;
}
And then called as such;
InitialSteps();
executeThisFunctionInAnyCase();
If C++11 lambdas are available (there was no C++11 tag in the OP, but they may still be an option), then we can forgo the seperate function and wrap this up into a lambda.
// Capture by reference (variable access may be required)
auto initialSteps = [&]() {
// any additional code
bool conditionA = executeStepA();
if (!conditionA)
return;
// any additional code
bool conditionB = executeStepB();
if (!conditionB)
return;
// any additional code
bool conditionC = executeStepC();
if (!conditionC)
return;
};
initialSteps();
executeThisFunctionInAnyCase();

If you dislike goto and dislike do { } while (0); loops and like to use C++ you can also use a temporary lambda to have the same effect.
[&]() { // create a capture all lambda
if (!executeStepA()) { return; }
if (!executeStepB()) { return; }
if (!executeStepC()) { return; }
}(); // and immediately call it
executeThisFunctionInAnyCase();

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)

Have your execute functions throw an exception if they fail instead of returning false. Then your calling code could look like this:
try {
executeStepA();
executeStepB();
executeStepC();
}
catch (...)
Of course I'm assuming that in your original example the execution step would only return false in the case of an error occuring inside the step?

A lot of good answers already, but most of them seem to tradeoff on some (admittedly very little) of the flexibility. A common approach which doesn't require this tradeoff is adding a status/keep-going variable. The price is, of course, one extra value to keep track of:
bool ok = true;
bool conditionA = executeStepA();
// ... possibly edit conditionA, or just ok &= executeStepA();
ok &= conditionA;
if (ok) {
bool conditionB = executeStepB();
// ... possibly do more stuff
ok &= conditionB;
}
if (ok) {
bool conditionC = executeStepC();
ok &= conditionC;
}
if (ok && additionalCondition) {
// ...
}
executeThisFunctionInAnyCase();
// can now also:
return ok;

You just do this..
coverConditions();
executeThisFunctionInAnyCase();
function coverConditions()
{
bool conditionA = executeStepA();
if (!conditionA) return;
bool conditionB = executeStepB();
if (!conditionB) return;
bool conditionC = executeStepC();
if (!conditionC) return;
}
99 times of 100, this is the only way to do it.
Never, ever, ever try to do something "tricky" in computer code.
By the way, I'm pretty sure the following is the actual solution you had in mind...
The continue statement is critical in algorithmic programming. (Much as, the goto statement is critical in algorithmic programming.)
In many programming languages you can do this:
-(void)_testKode
{
NSLog(#"code a");
NSLog(#"code b");
NSLog(#"code c\n");
int x = 69;
{
if ( x == 13 )
{
NSLog(#"code d---\n");
continue;
}
if ( x == 69 )
{
NSLog(#"code e---\n");
continue;
}
if ( x == 13 )
{
NSLog(#"code f---\n");
continue;
}
}
NSLog(#"code g");
}
(Note first of all: naked blocks like that example are a critical and important part of writing beautiful code, particularly if you are dealing with "algorithmic" programming.)
Again, that's exactly what you had in your head, right? And that's the beautiful way to write it, so you have good instincts.
However, tragically, in the current version of objective-c (Aside - I don't know about Swift, sorry) there is a risible feature where it checks if the enclosing block is a loop.
Here's how you get around that...
-(void)_testKode
{
NSLog(#"code a");
NSLog(#"code b");
NSLog(#"code c\n");
int x = 69;
do{
if ( x == 13 )
{
NSLog(#"code d---\n");
continue;
}
if ( x == 69 )
{
NSLog(#"code e---\n");
continue;
}
if ( x == 13 )
{
NSLog(#"code f---\n");
continue;
}
}while(false);
NSLog(#"code g");
}
So don't forget that ..
do { } while(false);
just means "do this block once".
ie, there is utterly no difference between writing do{}while(false); and simply writing {} .
This now works perfectly as you wanted...here's the output...
So, it's possible that's how you see the algorithm in your head. You should always try to write what's in your head. ( Particularly if you are not sober, because that's when the pretty comes out! :) )
In "algorithmic" projects where this happens a lot, in objective-c, we always have a macro like...
#define RUNONCE while(false)
... so then you can do this ...
-(void)_testKode
{
NSLog(#"code a");
int x = 69;
do{
if ( x == 13 )
{
NSLog(#"code d---\n");
continue;
}
if ( x == 69 )
{
NSLog(#"code e---\n");
continue;
}
if ( x == 13 )
{
NSLog(#"code f---\n");
continue;
}
}RUNONCE
NSLog(#"code g");
}
There are two points:
a, even though it's stupid that objective-c checks the type of block a continue statement is in, it's troubling to "fight that". So it's a tough decision.
b, there's the question should you indent, in the example, that block? I lose sleep over questions like that, so I can't advise.
Hope it helps.

In C++ (the question is tagged both C and C++), if you can't change the functions to use exceptions, you still can use the exception mechanism if you write a little helper function like
struct function_failed {};
void attempt(bool retval)
{
if (!retval)
throw function_failed(); // or a more specific exception class
}
Then your code could read as follows:
try
{
attempt(executeStepA());
attempt(executeStepB());
attempt(executeStepC());
}
catch (function_failed)
{
// -- this block intentionally left empty --
}
executeThisFunctionInAnyCase();
If you're into fancy syntax, you could instead make it work via explicit cast:
struct function_failed {};
struct attempt
{
attempt(bool retval)
{
if (!retval)
throw function_failed();
}
};
Then you can write your code as
try
{
(attempt) executeStepA();
(attempt) executeStepB();
(attempt) executeStepC();
}
catch (function_failed)
{
// -- this block intentionally left empty --
}
executeThisFunctionInAnyCase();

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:
template<typename F> struct ScopeExit
{
ScopeExit(F f) : fn(f) { }
~ScopeExit()
{
fn();
}
F fn;
};
template<typename F> ScopeExit<F> MakeScopeExit(F f) { return ScopeExit<F>(f); };
#define STR_APPEND2_HELPER(x, y) x##y
#define STR_APPEND2(x, y) STR_APPEND2_HELPER(x, y)
#define SCOPE_EXIT(code)\
auto STR_APPEND2(scope_exit_, __LINE__) = MakeScopeExit([&](){ code })
This will allow you to return early from the function and ensure whatever cleanup code you define is always executed upon scope exit:
SCOPE_EXIT(
delete pointerA;
delete pointerB;
close(fileC); );
if (!executeStepA())
return;
if (!executeStepB())
return;
if (!executeStepC())
return;
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):
bool (*step[])() = {
&executeStepA,
&executeStepB,
&executeStepC,
...
};
for (int i = 0; i < numberOfSteps; i++) {
bool condition = step[i]();
if (!condition) {
break;
}
}
executeThisFunctionInAnyCase();
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:
Step *steps[] = {
stepA,
stepB,
stepC,
...
};
for (int i = 0; i < numberOfSteps; i++) {
Step *step = steps[i];
if (!step->execute()) {
break;
}
}
executeThisFunctionInAnyCase();

Assuming you don't need individual condition variables, inverting the tests and using the else-falthrough as the "ok" path would allow you do get a more vertical set of if/else statements:
bool failed = false;
// keep going if we don't fail
if (failed = !executeStepA()) {}
else if (failed = !executeStepB()) {}
else if (failed = !executeStepC()) {}
else if (failed = !executeStepD()) {}
runThisFunctionInAnyCase();
Omitting the failed variable makes the code a bit too obscure IMO.
Declaring the variables inside is fine, no worry about = vs ==.
// keep going if we don't fail
if (bool failA = !executeStepA()) {}
else if (bool failB = !executeStepB()) {}
else if (bool failC = !executeStepC()) {}
else if (bool failD = !executeStepD()) {}
else {
// success !
}
runThisFunctionInAnyCase();
This is obscure, but compact:
// keep going if we don't fail
if (!executeStepA()) {}
else if (!executeStepB()) {}
else if (!executeStepC()) {}
else if (!executeStepD()) {}
else { /* success */ }
runThisFunctionInAnyCase();

If your code is as simple as your example and your language supports short-circuit evaluations, you could try this:
StepA() && StepB() && StepC() && StepD();
DoAlways();
If you are passing arguments to your functions and getting back other results so that your code cannot be written in the previous fashion, many of the other answers would be better suited to the problem.

As Rommik mentioned, you could apply a design pattern for this, but I would use the Decorator pattern rather than Strategy since you are wanting to chain calls. If the code is simple, then I would go with one of the nicely structured answers to prevent nesting. However, if it is complex or requires dynamic chaining, then the Decorator pattern is a good choice. Here is a yUML class diagram:
Here is a sample LinqPad C# program:
void Main()
{
IOperation step = new StepC();
step = new StepB(step);
step = new StepA(step);
step.Next();
}
public interface IOperation
{
bool Next();
}
public class StepA : IOperation
{
private IOperation _chain;
public StepA(IOperation chain=null)
{
_chain = chain;
}
public bool Next()
{
bool localResult = false;
//do work
//...
// set localResult to success of this work
// just for this example, hard coding to true
localResult = true;
Console.WriteLine("Step A success={0}", localResult);
//then call next in chain and return
return (localResult && _chain != null)
? _chain.Next()
: true;
}
}
public class StepB : IOperation
{
private IOperation _chain;
public StepB(IOperation chain=null)
{
_chain = chain;
}
public bool Next()
{
bool localResult = false;
//do work
//...
// set localResult to success of this work
// just for this example, hard coding to false,
// to show breaking out of the chain
localResult = false;
Console.WriteLine("Step B success={0}", localResult);
//then call next in chain and return
return (localResult && _chain != null)
? _chain.Next()
: true;
}
}
public class StepC : IOperation
{
private IOperation _chain;
public StepC(IOperation chain=null)
{
_chain = chain;
}
public bool Next()
{
bool localResult = false;
//do work
//...
// set localResult to success of this work
// just for this example, hard coding to true
localResult = true;
Console.WriteLine("Step C success={0}", localResult);
//then call next in chain and return
return (localResult && _chain != null)
? _chain.Next()
: true;
}
}
The best book to read on design patterns, IMHO, is Head First Design Patterns.

Several answers hinted at a pattern that I saw and used many times, especially in network programming. In network stacks there is often a long sequence of requests, any of which can fail and will stop the process.
The common pattern was to use do { } while (false);
I used a macro for the while(false) to make it do { } once; The common pattern was:
do
{
bool conditionA = executeStepA();
if (! conditionA) break;
bool conditionB = executeStepB();
if (! conditionB) break;
// etc.
} while (false);
This pattern was relatively easy to read, and allowed objects to be used that would properly destruct and also avoided multiple returns making stepping and debugging a bit easier.

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:
interface StepState{
public StepState performStep();
}
An implementation would work as follows:
class StepA implements StepState{
public StepState performStep()
{
performAction();
if(condition) return new StepB()
else return null;
}
}
And so on. Then you can substitute the big if condition with:
Step toDo = new StepA();
while(toDo != null)
toDo = toDo.performStep();
executeThisFunctionInAnyCase();

It's seems like you want to do all your call from a single block.
As other have proposed it, you should used either a while loop and leave using break or a new function that you can leave with return (may be cleaner).
I personally banish goto, even for function exit. They are harder to spot when debugging.
An elegant alternative that should work for your workflow is to build a function array and iterate on this one.
const int STEP_ARRAY_COUNT = 3;
bool (*stepsArray[])() = {
executeStepA, executeStepB, executeStepC
};
for (int i=0; i<STEP_ARRAY_COUNT; ++i) {
if (!stepsArray[i]()) {
break;
}
}
executeThisFunctionInAnyCase();

Because you also have [...block of code...] between executions, I guess you have memory allocation or object initializations. In this way you have to care about cleaning all you already initialized at exit, and also clean it if you will meet problem and any of functions will return false.
In this case, best what I had in my experience (when I worked with CryptoAPI) was creating small classes, in constructor you initialize your data, in destructor you uninitialize it. Each next function class have to be child of previous function class. If something went wrong - throw exception.
class CondA
{
public:
CondA() {
if (!executeStepA())
throw int(1);
[Initialize data]
}
~CondA() {
[Clean data]
}
A* _a;
};
class CondB : public CondA
{
public:
CondB() {
if (!executeStepB())
throw int(2);
[Initialize data]
}
~CondB() {
[Clean data]
}
B* _b;
};
class CondC : public CondB
{
public:
CondC() {
if (!executeStepC())
throw int(3);
[Initialize data]
}
~CondC() {
[Clean data]
}
C* _c;
};
And then in your code you just need to call:
shared_ptr<CondC> C(nullptr);
try{
C = make_shared<CondC>();
}
catch(int& e)
{
//do something
}
if (C != nullptr)
{
C->a;//work with
C->b;//work with
C->c;//work with
}
executeThisFunctionInAnyCase();
I guess it is best solution if every call of ConditionX initialize something, allocs memory and etc. Best to be sure everything will be cleaned.

Here's a trick I've used on several occasions, in both C-whatever and Java:
do {
if (!condition1) break;
doSomething();
if (!condition2) break;
doSomethingElse()
if (!condition3) break;
doSomethingAgain();
if (!condition4) break;
doYetAnotherThing();
} while(FALSE); // Or until(TRUE) or whatever your language likes
I prefer it over nested ifs for the clarity of it, especially when properly formatted with clear comments for each condition.

To improve on Mathieu's C++11 answer and avoid the runtime cost incurred through the use of std::function, I would suggest to use the following
template<typename functor>
class deferred final
{
public:
template<typename functor2>
explicit deferred(functor2&& f) : f(std::forward<functor2>(f)) {}
~deferred() { this->f(); }
private:
functor f;
};
template<typename functor>
auto defer(functor&& f) -> deferred<typename std::decay<functor>::type>
{
return deferred<typename std::decay<functor>::type>(std::forward<functor>(f));
}
This simple template class will accept any functor that can be called without any parameters, and does so without any dynamic memory allocations and therefore better conforms to C++'s goal of abstraction without unnecessary overhead. The additional function template is there to simplify use by template parameter deduction (which is not available for class template parameters)
Usage example:
auto guard = defer(executeThisFunctionInAnyCase);
bool conditionA = executeStepA();
if (!conditionA) return;
bool conditionB = executeStepB();
if (!conditionB) return;
bool conditionC = executeStepC();
if (!conditionC) return;
Just as Mathieu's answer this solution is fully exception safe, and executeThisFunctionInAnyCase will be called in all cases. Should executeThisFunctionInAnyCase itself throw, destructors are implicitly marked noexceptand therefore a call to std::terminate would be issued instead of causing an exception to be thrown during stack unwinding.

an interesting way is to work with exceptions.
try
{
executeStepA();//function throws an exception on error
......
}
catch(...)
{
//some error handling
}
finally
{
executeThisFunctionInAnyCase();
}
If you write such code you are going somehow in the wrong direction. I wont see it as "the problem" to have such code, but to have such a messy "architecture".
Tip: discuss those cases with a seasoned developer which you trust ;-)

Related

How to deal with declaration of the primitive type without the initial value known (C++)?

In some cases it happens for me to declare a variable without knowing its value first like:
int a;
if (c1) {
a = 1;
} else if (c2) {
a = 2;
} else if (c3) {
a = -3;
}
do_something_with(a);
Is it the standard professional practice to assign some clearly wrong value like -1000 anyway (making potential bugs more reproducible) or it is preferred not to add the code that does nothing useful as long as there are no bugs? From one side, looks reasonable to remove randomness, from the other side, magical and even "clearly wrong" numbers somehow do not look attractive.
In many cases it is possible to declare when the value is first known, or use a ternary operator, but here we would need it nested so also rather clumsy.
Declaring inside the block would move the variable out of the scope prematurely.
Or would this case justify the usage of std::optional<int> a and assert(a) later, making sure we have the value?
EDIT: The bugs I am talking about would occur if suddenly all 3 conditions are false that should "absolutely never happen".
As far as I know the most popular and safest way is using inline lambda call. Note that the if should be exhaustive (I added SOME_DEFAULT_VALUE as a placeholder). I suppose that if you don't know what to put in final else block you should consider a few options:
using optional and putting none in the else,
throwing exception that describes the problem,
putting assert if logically this situation should never happen
const int a = [&] {
if (c1) {
return 1;
} else if (c2) {
return 2;
} else if (c3) {
return -3;
} else {
return SOME_DEFAULT_VALUE;
}
}();
do_something_with(a);
In a situation when the initialization logic duplicates somewhere you can simply extract the lambda to a named function as other answers suggest
In my opinion, the safest option, if you dont want this other value (its just useless), then it may lead to really subtle bug which may be hard to find. Therefore I would throw an expectation when any of the conditions is not met:
int get_init_value(bool c1, bool c2, bool c3) {
if (c1) { return 1; }
else if (c2) { return 2; }
else if (c3) { return -3; }
throw std::logic_error("noone of conditions to define value was met");
}
That way we avoid getting some weird values that want actually match our code, but they would compile anyways ( debugging it may take a lot of time). I consider it way better than just assigning it some clearly wrong value.
Opinion based answer!
I know the example is a simplification of a real, more complex example, but IMHO it seems nowadays this kind of design issue emerge more often, and people sometimes kinda tend to over-complicate it.
Isn't it the whole purpose of a variable to hold some value? Thus isn't having a default value for this variable also a feasible thing?
So what exactly is wrong with:
int a = -1000; // or some other value meant to used for undefined
if (c1) {
a = 1;
} else if (c2) {
a = 2;
} else if (c3) {
a = -3;
}
do_something_with(a);
It is simple and readable... No lambdas, exceptions and other stuff making the code unnecessary complicated...
Or like:
int a;
if (c1) {
a = 1;
} else if (c2) {
a = 2;
} else if (c3) {
a = -3;
} else {
a = -1000; // default for unkown state
}
do_something_with(a);
You could introduce a constant const int undefined = -1000; and use the constant.
Or an enum if c1, c2, c3 are states in some sort (which it most likely is)...
You could rearrange the code to eliminate the variable if it is not needed elsewhere.
if (c1) {
do_something_with(1);
} else if (c2) {
do_something_with(2);
} else if (c3) {
do_something_with(-3);
}
I would introduce a default value. I'm usually using MAX value of the type for this.
Shortest you can do this with the ternary operator like this:
#include <climits>
int a = c1 ? 1 : c2 ? 2 : c3 ? -3 : INT_MAX;
do_something_with(a);
I understand your real code is much more complicated than the outline presented, but IMHO the main problem here is
should we do_something_with(a) at all if a is undefined,
rather than
what the initial value should be.
And the solution might be adding explicitly some status flag like a_is_defined to the actual parameter a instead of using magic constans.
int a = 0;
bool a_is_defined = false;
When you set them both according to c... conditions and pass them to do_something() you'll be able to make a clear distinction between a specific if(a_is_defined) {...} path and a default (error handling?) else {...}.
Or even provide separate routines to explicitly handle both paths one level earlier: if(a_is_defined) do_someting_with(a); else do_something_else();.

Elegant way for "if(T t = ...) { } else return t;"?

Is there a better way for this "idiom"?
if(State s = loadSomething()) { } else return s;
In other words, I want to do something, which may return an error (with a message) or a success state, and if there was an error I want to return it. This can become very repetitive, so I want to shorten it. For example
if(State s = loadFoobar(&loadPointer, &results)) { } else return s;
if(State s = loadBaz(&loadPointer, &results)) { } else return s;
if(State s = loadBuz(&loadPointer, &results)) { } else return s;
This must not use exceptions which I would favor otherwise (unsuitable for this build). I could write up a little class BooleanNegator<State> that stores the value, and negates its boolean evaluation. But I want to avoid doing this ad-hoc, and prefer a boost/standard solution.
You could do:
for (State s = loadSomething(); !s; ) return s;
but I am not sure if it is more elegant, and it is definitely less readable...
I assume the context is something like
State SomeFunction()
{
if(State s = loadSomething()) { } else return s;
return do_something_else();
}
without throwing exceptions where do_something_else() does something of relevance to SomeFunction() and returns a State. Either way, the result of continuing within the function needs to result in a State being returned, as falling off the end will cause the caller to exhibit undefined behaviour.
In that case, I would simply restructure the function to
State SomeFunction()
{
if (State s = loadSomething())
return do_something_else();
else
return s;
}
Implicit assumptions are that State has some operator (e.g. operator bool()) that can be tested, that copying a State is possible (implied by the existence of a loadSomething() that returns one) and relatively inexpensive, and that two instances of State can exist at one time.
Aside from some smart/hacky uses of different keywords to get the same behavior, or adding more-or-less complex extra templates or macros to get unless() keyword or to somehow manage to inject ! operator, I'd stick to just the basic things.
This is one of the places I'd (probably) inject extra "unnecessary" brackets:
void someFunction()
{
// some other code
{ State s = loadSomething(); if(!s) return s; }
// some other code
}
However, in this exact case, I'd expand it to emphasise the return keyword, which can be easily overlooked when it's squashed to a one-liner. So, unless the one-liner is repeated many times and unless it's clear&obvious that there's a return inside, I'd probably write:
void someFunction()
{
// some other code
{
State s = loadSomething();
if(!s)
return s;
}
// some other code
}
It might look like elevating the scope of the s, but actually it is equivalent to declaring State s in if(). All thanks to the extra brackets which explicitly limit the visibility of local s.
However, some people just "hate" seeing { .. } not coupled with a keyword/class/function/etc, or even consider it to be unreadable due to "suggesting that a if/while/etc keyword was accidentally deleted".
One more idea came to me after you added the repetitive example. You could have tried a trick known from scripting languages where && and || may return a non-bool values:
State s = loadFoobar(&loadPointer, &results);
s = s || loadBaz(&loadPointer, &results);
s = s || loadBuz(&loadPointer, &results);
if(!s) return s;
however there's a problem: in contrast to script languages, in C++ such overloads of && and || lose their short-circuit semantics which makes this attempt pointless.
However, as dyp pointed out the obvious thing, once the s scope is elevated, now simple if can be introduced back. Its visibility can be limited back again with extra {}:
{
State s;
if(!(s = loadFoobar(&loadPointer, &results))) return s;
if(!(s = loadBaz(&loadPointer, &results))) return s;
if(!(s = loadBuz(&loadPointer, &results))) return s;
}

Is there any benefit to split Get() into Has() and Get() of containers?

Say I have a vector<MyClass>, and a GetMyClass(), like:
std::vector<MyClass> mcs; // assume mcs has some elements...
MyClass* GetMyClass()
{
auto it = std::find_if(mcs.begin(), mcs.end(),
[](const MyClass& mc)
{
return mc.condition() == true;
});
if (it == mcs.end())
return nullptr;
else
return &(*it);
}
This is very conventional, the user calls it and check the return value is nullptr or not. But bad things happen if the user forgot to check. The nullptr check is annoying, and is not always happening. Besides, this function is kind-of a mix of both checking (if there is any valid MyClass) and getting (one MyClass).
P.S. MyClass.condition() == true; is just a simplification, real case could be more complicated.
So I came across to make 2 functions:
bool HasMyClass()
{
auto it = std::find_if(mcs.begin(), mcs.end(),
[](const MyClass& mc)
{
return mc.condition() == true;
});
return (it == mcs.end());
}
MyClass& GetMyClass()
{
auto it = std::find_if(mcs.begin(), mcs.end(),
[](const MyClass& mc)
{
return mc.condition() == true;
});
return (*it);
}
If the user wants to know the existence of MyClass then he calls HasMyClass();
If the user wants to get one MyClass and is very sure there must be one, then he calls GetMyClass() directly. If the user wants one MyClass but is not sure, then he calls both of them.
To eliminate code duplication and to avoid redundant execution, I modify it to be:
std::vector<MyClass> mcs; // assume mcs has some elements...
// std::vector<MyClass>::iterator temp; // originally this
MyClass* temp = nullptr; // changed to this according to Hsi-Hung Shih's advice
bool HasMyClass()
{
auto it = std::find_if(mcs.begin(), mcs.end(),
[](const MyClass& mc)
{
return mc.condition() == true;
});
if (it == mcs.end())
{
temp = nullptr;
return false;
}
else
{
temp = &(*it);
return true;
}
}
MyClass& GetMyClass()
{
if (temp == nullptr)
{
HasMyClass();
}
MyClass& mc = (*temp);
temp = nullptr;
return mc;
}
My question is:
Is there any benefit to make an additional Has() function?
If so, will this ease any burden of the user? Will this make the intention of code use more clear? Is the extra complication worth it?
Thanks!
I would advise keeping the original implementation of GetMyClass. I would add HasMyClass as a convenience function for those cases where that's the only information needed to fork.
You can implement HasMyClass by using GetMyClass. It's a trivial implementation.
bool HasMyClass()
{
return (GetMyClass() != nullptr);
}
If a function uses,
if ( HasMyClass() )
{
MyClass* c = GetMyClass();
}
There will be two searches. This is a bad use of the functions but you can't stop them.
A better use of HasMyClass is:
if ( HasMyClass() )
{
// Follow path 1 (does not involve call to GetMyClass)
}
else
{
// Follow path 2 (does not involve call to GetMyClass either)
}
and is very sure there must be one
Gives already the answer: If you can not be sure, you can not handle the return value without checking.
But this kind of programming looks like an old posix interface where every retval must be checked. In c++ you have a lot more functionality from the stl without writing such code self. I would advice you to have a look in <algorithm>. Think about functor pattern, where you directly give the action to the search function. Take a look at for_each and others.
http://www.cplusplus.com/reference/algorithm/for_each/
http://www.cplusplus.com/reference/algorithm/copy_if/
Or simply all:
http://www.cplusplus.com/reference/algorithm/
I believe you can do a lot with stl functionality. Writing own search functions, accessing them, checking retvals and do something with the value/iterator must normally not be done by hand crafted code.
The second attempt could be throwing of exceptions like throw NotFound_t();
Checking returned value for potential failure is common API design, so the programmers are supposed to be familiar with it and can use it with ease. If they forget to check it, they will know when they dereference it.
You can throw exception when none is found, but finding nothing in a container is usually not an exceptional thing, and it had better not throw.
By the way, your code is also dangerous, because the iterator "temp" could be invalid after your previous find. It could result from item being removed from the vector. Function with unclear side effects is very bad.
In sum, make your API familiar to people. Don't complicate the code just to make it look cute, like allowing people to not checking the return value for potential failure.
Edit
If your data could be nullptr, you can just define a data class to return, in which it could indicate failure state. If you are lazy, you could use std::pair to do this.
struct Data {
bool is_failed;
MyClass* data;
};
A usual implementation is to change the interface to pass the pointer as a parameter and to return whether or not the object was found :
bool TryGetMyClass(MyClass* ptr)
{
auto it = std::find_if(mcs.begin(), mcs.end(),
[](const MyClass& mc)
{
return mc.condition() == true;
});
if (it == mcs.end())
{
ptr = nullptr;
return false;
}
else
{
ptr = &(*it);
return true;
}
}
Usage example :
if(TryGetMyClass(ptr))
... // Ok, ptr not null
else
... // Handle null pointer
To be honest, what these functions show is that you're just not achieving anything by wrapping STL methods. Those already have a well-established pattern to communicate "not found", and C++ programmers are already familiar with that. Your method is confusing even to you.
Instead, what you should do is provide decent predicates for use in std::find.

Error: switch quantity no an integer. How do I make a character code for multiple words [duplicate]

I have researched my issue all over StackOverflow and multi-google links, and I am still confused. I figured the best thing for me is ask...
Im creating a simple command line calculator. Here is my code so far:
const std::string Calculator::SIN("sin");
const std::string Calculator::COS("cos");
const std::string Calculator::TAN("tan");
const std::string Calculator::LOG( "log" );
const std::string Calculator::LOG10( "log10" );
void Calculator::set_command( std::string cmd ) {
for(unsigned i = 0; i < cmd.length(); i++)
{
cmd[i] = tolower(cmd[i]);
}
command = cmd;
}
bool Calculator::is_legal_command() const {
switch(command)
{
case TAN:
case SIN:
case COS:
case LOG:
case LOG10:
return true;
break;
default:
return false;
break;
}
}
the error i get is:
Calculator.cpp: In member function 'bool Calculator::is_trig_command() const':
Calculator.cpp: error: switch quantity not an integer
Calculator.cpp: error: 'Calculator::TAN' cannot appear in a constant-expression
Calculator.cpp: error: 'Calculator::SIN' cannot appear in a constant-expression
Calculator.cpp: error: 'Calculator::COS' cannot appear in a constant-expression
The mighty internet, it says strings are allowed to be used in switch statements.
Thanks everyone, I appreciate your help.
In switch, the expression must be of "an integral type or of a class type for which there is an unambiguous conversion to integral type" (quoting VS2008 docs).
A string class doesn't have "unambiguous conversion to integral type", like a char does.
As a work-around:
Create a map<string, int> and switch on the value of the map: switch(command_map[command])
`
Do a set of if/else instead of switch. Much more annoying and hard to read, so I'd recommend the map route.
As an aside, an even better solution for really complicated logic like that is to improve the mapping solution to get rid of switch completely and instead go with a function lookup: std::map<std::string, functionPointerType>. It may not be needed for your specific case, but is MUCH faster for complicated very long look-up logic.
As others and the compiler commented, strings are not allowed with switch. I would just use if
bool Calculator::is_legal_command() const {
if(command == TAN) return true;
if(command == SIN) return true;
if(command == COS) return true;
if(command == LOG) return true;
if(command == LOG10) return true;
return false;
}
I don't think that's any more complicated, and it's about as fast as it could get. You could also use my switch macro, making it look like
bool Calculator::is_legal_command() const {
sswitch(command)
{
scase (TAN):
scase (SIN):
scase (COS):
scase (LOG):
scase (LOG10):
return true;
sdefault():
return false;
}
}
(having break after a return is dead code, and so should be avoided).
Strings cannot be used in switch statements in C++. You'll need to turn this into if/else if, like this:
if (command == "tan")
{
// ...
}
else if (command == "cos")
{
// ...
}
// ...
Not sure which mighty Internet you've been reading, but C++ doesn't allow strings in switch statements. (C# does, though.)
You need to convert your switch statement to a chain of if-else if-else statements that test equality.
Rather than a switch.
I would use a command pattern. Then use a std::map to map the function name to the command object.
Something like this:
#include <math.h>
#include <map>
#include <string>
#include <iostream>
class Function
{
public:
// Easy public API that just uses the normal function call symantics
double operator()(double value) { return this->doWork(value);}
virtual ~Function() {}
private:
// Virtual function where the work is done.
virtual double doWork(double value) = 0;
};
// A sin/cos function
class Sin: public Function { virtual double doWork(double value) { return sin(value); } };
class Cos: public Function { virtual double doWork(double value) { return cos(value); } };
// A class that holds all the functions.
// A function name is mapped to a function object.
class FuncMap
{
public:
FuncMap()
{
// Constructor sets up the map
functions["sin"] = &sinFunc;
functions["cos"] = &cosFunc;
}
Function* getFunction(std::string command) const
{
// Default result not found.
Function* result = NULL;
std::map<std::string, Function*>::const_iterator find;
// Look in the map to see if we find the value.
// If it exists then find will not point at end()
if ((find = functions.find(command)) != functions.end())
{
// Get the pointer to the function
result = find->second;
}
return result;
}
private:
Sin sinFunc;
Cos cosFunc;
std::map<std::string, Function*> functions;
};
// Declaring it globally for ease of use.
FuncMap functions;
int main()
{
// SImple example of usage.
Function* func = functions.getFunction("sin");
if (func == NULL)
{
std::cout << "No Function sin()\n";
exit(1);
}
std::cout << "Result: " << (*func)(12.34) << "\n";
}
The compiler error tells you everything you need to know. Only integral types may be compared in switch statements.
I'm not sure which "mighty internet" told you otherwise, but it was mighty wrong.
Strings cannot be used as constants in switch statements in c++. You can either use a map, a series of if's or you can move from representing your commands as strings to an enum. Parse from string to enum once, then use a switch like you do now. Note that your string parsing may require the same mechanism (map/if's), but depending on your use case using one approach over the other may improve readability. I'm not going to say anything on which approach is more readable.

Should I avoid "goto" in situations like this?

I was making a "concatenating iterator", i.e. an iterator that would iterate over the ints in an int**.
Its constructor needs:
An array of T**, representing the beginning of each sub-array.
An array of T**, representing the end of each sub-array.
Lo and behold, I ran across a situation where goto seemed to be appropriate.
But something within me screamed "NO!!" so I thought I'd come here and ask:
Should I try avoid goto situations like this? (Does it improve the readability if I do?)
#include <algorithm>
template<class T>
class lazy_concat_iterator
{
// This code was meant to work for any valid input iterator
// but for easier reading, I'll assume the type is: T**
mutable T** m_endIt; // points to an array of end-pointers
mutable T** m_it; // points to an array of begin-pointers
mutable bool m_started; // have we started iterating?
mutable T* m_sub; // points somewhere in the current sub-array
mutable T* m_subEnd; // points to the end of the current sub-array
public:
lazy_concat_iterator(T** begins, T** ends)
: m_it(begins), m_endIt(ends), m_started(false) { }
void ensure_started() const
{
if (!m_started)
{
m_started = true;
INIT:
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub == m_subEnd) // End of this subarray?
{
++m_it;
++m_endIt;
goto INIT; // try next one <<< should I use goto here?
}
}
}
};
How you could use it:
#include <vector>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
vector<char*> beginnings(argv, argv + argc);
vector<char*> endings;
for (int i = 0; i < argc; i++)
endings.push_back(argv[i] + strlen(argv[i]));
lazy_concat_iterator<char> it(&beginnings[0], &endings[0]);
it.ensure_started(); // 'it' would call this internally, when dereferenced
}
Yes, you can and should avoid goto, for example this code should do the equivalent for what yours does from the INIT label (this also works for input iterators which was a "hidden requirement" as it doesn't dereference m_it and m_endIt an extra time once the condition is met unlike my previous transformation):
while ((m_subIt = *m_it) == (m_subEnd = *m_endIt))
{
++m_it;
++m_endIt;
}
Previous answer attempt:
Even a forever loop would be clearer and neater than a goto. It highlights the obvious "never terminate" possibility even better.
for (;;)
{
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub != m_subEnd)
break;
++m_it;
++m_endIt;
}
Although I don't see why you need to assign to m_subEnd and m_subIt inside the loop. If you don't you can rewrite this as a while loop:
while (*m_it == *m_endIt)
{
++m_it;
++m_endIt;
}
m_subIt = *m_it;
m_subEnd = *m_endIt;
while (*m_it == *m_endIt)
{
++m_it;
++m_endIt;
}
m_sub = *m_it;
m_subEnd = *m_endIt;
Maybe no for loop, but maybe a do-while?
do {
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub == m_subEnd) // End of this subarray?
{
++m_it;
++m_endIt;
}
} while (m_sub == m_subEnd);
If you don't want to do the comparison twice and still avoid using one of goto's stealth cousins break or continue:
bool anotherround = FALSE;
do {
m_sub = *m_it;
m_subEnd = *m_endIt;
anotherround = m_sub == m_subEnd
if (anotherround) // End of this subarray?
{
++m_it;
++m_endIt;
}
} while (anotherround);
With your knowledge of the context I'm sure you can invent better varnames, but that's the idea.
Regarding a goto's influence on readability: for me the main issue with a goto herey is that it forces the programmer to memorize a potential nonlogical movement in the code - all of a sudden the code can jump almost anywhere. If you use control structures, even if you have to introduce some extra lines or whatnot, the program continues to behave as expected and follow the flow. And in the long run, that's what readability is all about.
Don't use a goto. The only case when a goto can be forgiven is if you have a complicated function (which you shouldn't have anyways) and you want to have a centralized exit/cleanup part at the end of the function, where you could goto upon different errors at different parts of the function, or fall through upon success.
All in all, you should use a do-while loop here.
People created middle and high level compilers with using assembler(and high-level assembler). Assembler has many jmp jnz jg jl commands act like goto. They made it this far. Cant you do the same? If you can't then you answered your own question.
I cant say the same thing for interpreters.