Evaluate expressions until one returns true - c++

I have a savePotentiometerState(...) -function, which returns true if the there were changes to save, and false if nothing was done. Further, I know that on any single pass through my main loop, at most one of the potentiometers may have changed (due to the way they're read out).
This is on a very time-constrained embedded platform, so it's important (or at least matters) that I don't call savePotentiometerState more often than I have to. However, the code I come up with naturally seems silly, something likely to end up at thedailywtf:
if (!savePotentiometerState(pot1))
if (!savePotentiometerState(pot2))
...
if (!savePotentiometerState(potn));
Another way to do this would be to use short-circuit evaluation:
const bool retval = savePotentiometerState(pot1) || savePotentiometerState(pot2) || ... || savePotentiometerState(potn);
I suppose I could even drop the assignment here. But this doesn't feel like good style either, since I'm abusing the short circuiting of the || operator.
The various potn objects are member variables of the containing class, so there's no obvious way to write this as a loop.
I feel like I'm missing something obvious here, so my question is: is there an idiomatic/easy to read way to do this, which doesn't sacrifice efficiency? If it matters, I'm using C++17.

Loop seems the way to go:
for (auto& pot : {std::ref(pot1), std::ref(pot2), /*..,*/ std::ref(potn)}) {
if (savePotentiometerState(pot)) {
break;
}
}

Since you can use C++17 you can leverage fold expressions and write a helper function to do the evaluation for you.
template<typename... Args>
bool returtnPotentiometerState(Args&&... args)
{
return (... || savePotentiometerState(args));
}
and then you would call it like
if (returtnPotentiometerState(pot1, pot2, ..., potn))
This means you don't have a loop, and you get short circuiting.

Personally - I'd avoid the algorithm you're using.
I'd save the state for every pot all the time; and track the current and previous values; and then only call a given callback if if the value had changed.
This way, savePotState is always as fast as it needs to be for a given pot; and you'll never get into the state where pot1 to pot(n-1) can block potn from being read.

Related

Is (bool | bool) safe?

I'm writing some C++ code, and I'd like to call two functions (checkXDirty and checkYDirty), and return true if either returns true. I need to evaluate both even if one returns true, so my first thought was to use
return checkXDirty() | checkYDirty();
This looks a little weird (dirty, perhaps). Does this always produce the correct result in C++? What about C, with the _Bool type? (This code might end up being adapted for either language, and I don't want unpleasant surprises when I port the code).
I need to evaluate both even if one returns true, so my first thought was to use...
Then stop trying to be tricky and making your code fit in as few lines as possible. Just call both functions and make it obvious that they need to be called:
const bool x_dirty = is_x_dirty();
const bool y_dirty = is_y_dirty();
return x_dirty || y_dirty;
Next, rename or break apart your functions as is_xxx_dirty really should not be producing side effects. Your code is harder to maintain as a result
As long as the values are not indeterminate, it's technically OK to use the bitwise operators. However, since that's fraught with problems as a general coding habit, I would instead just write a little inline OR-function, and let the compiler optimize. The compiler is good at optimizing, so, let it.
return eitherOrBothTrue( checkXDirty(), checkYDirty() );
Or perhaps, if you're bold and dare to take on the challenge of explaining the code to those who will maintain it,
return !bothFalse( checkXDirty(), checkYDirty() );
Or now that I read #EdS' answer, is perhaps equally good to just store the values in variables, but do then add const, like this:
bool const xIsDirty = checkXDirty();
bool const yIsDirty = checkYDirty();
return xIsDirty || yIsDirty;

Is it good practice to check for null and check object properties in the same if statement

Is it good practice to check for null and check object properties in the same if statement?
Consider the following code:
if (jamesBlunt != null && jamesBlunt.isReallyBad()) {
// Don't buy his records
}
This particular code is in java and I know the expression is evaluated from left to right so technically it won't throw a NullPointerException but in general is this good practice in any language?
As you are using an OR statement there will be a NullPointerException if jamesBlunt is null. You should use and, because if the left statement is false, the whole expression will be false.
Use:
if (jamesBlunt != null && jamesBlunt.isReallyBad()) {
// Don't buy his records
}
When Java 7 is out, you could use the shortcut
if(jamesBlunt?.isReallyBad() {
// Don't buy his records
}
But until then the explicit check for null would be best practice. (In fact it would be best practice to not use jamesBlunt objects...)
I'll assume the || is a typo and you meant && :)
To answer your question: it depends.
Does it make sense for jamesBlunt to ever be null? If not, then it would be better practice to have something like this:
void buyARecord(Artist jamesBlunt) {
if (jamesBlunt == null) {
throw new IllegalArgumentException("James should never be null!");
}
}
If it does make sense for jamesBlunt to be null then your approach is fine, assuming null and isReallyBad mean the same thing semantically. If they mean different things semantically then you should probably not be combining them on one line.
You do need to be careful in other languages. Many (Java, C++, C# etc) will behave the same way, but some may evaluate from right-to-left or evaluate lazily. Take particular care with functional languages like Lisp and Scheme as they tend to behave differently to object oriented languages like Java and C#.
You want to use && instead of OR.
Yes, it is good practice to check for null in the same if statement, the alternative (nesting two ifs) is ugly because adds more indentation.
But checking before is also OK: specially if you want to do some error checking.
Personally, I would separate these. Null checking is the kind of thing one would do at the beginning of a function and is usually done to verify function parameters and are generally called "guard clauses". These checks will often raise an exception or return an error code as defined by the function.
These can lead to cleaner code below, avoiding multiple levels of nesting. It also prevents the need to repeat the null checks if there are other things you wish to test for on the object in question.

Nested If (x) checks - Better way to write this?

There are places where I check for valid pointers before I perform an operation with them; these checks can be nested pretty deeply sometimes.
For example, I have
if (a)
{
if (a->b())
{
if (a->b()->c())
{
a->b()->c()->DoSomething();
}
}
}
I really don't like the look of this. Is there a way to turn this into something more readable? Ideally,
if (a && a->b() && a->b()->c() )
{
...
}
would be great, but obviously would not work.
EDIT - nvm the example that I put up DOES work as everybody has pointed out. I did test it out to see if this works, but there was a bug in my code in my test. duh!
Why would the latter not work?
In C, && is a short-circuit operator, so it is evaluated from left to right, and if any evaluation is false, evaluation stops.
In fact, you could write:
a && a->b() && a->b()->c() && a->b()->c()->DoSomething();
Quoting from K&R1:
Expressions connected by && or || are evaluated from left to right, and it is guaranteed that evaluation will stop as soon as the truth or falsehood is known.
Therefore the latter example will work perfectly, as WhirlWind has noted.
1 The C Programming Language, Second Edition, Page 21.
Your second example does work in C/C++. It short circuits when the first FALSE value is hit.
You've seen from the other answers that using && will work, and will short-circuit the evaluation when a null pointer is encountered.
The uneasy programmer in me likes to avoid repeating method calls for tests like this since it avoids worrying if they are idempotent or not. One option is to rewrite like this
A* a;
B* b;
C* c;
if ((a=a()) && (b=a->b()) && (c=b->c())) {
c->doSomething();
}
Admittedly verbose and a bit clunky, but at least you know each method is called just once.
Why 'obviously would not work'? Since the && operator only evaluates the right term if the left is valid, the rewrite is perfectly safe.
Since you've already received the direct answer to your question I'll just mention that long chains of calls like you've got there are a code smell and you might consider a better design. Such a design might, in this case, include use of the null object pattern so that your call might just boil down to:
a->CDoSomething();
Chaining works, but it's not necessarily the best general-case answer, particularly because it obscures the failure point. I would instead suggest flattening the tests by inverting the logic so that it exits on failure.
if (!pa)
return Fail("No pa");
B* pb = pa->b();
if (!pb)
return Fail("No pb");
C* pc = b->c();
if (!pc)
return Fail("No pc");
pc->DoSomething();
Same thing, but flat and easy to read. Also, because it immediately handles the failure case, that doesn't get relegated to an else that you might never get around to writing.
In this example, I assumed you didn't want to just silently fail, so I added Fail as a helper that logs the text and returns false. You could also just throw an exception. In fact, if the various methods signaled their failure by throwing an appropriate exception instead of returning null, then all this would be unnecessary. If silent failure was desirable, then a null object pattern would be appropriate.
if (a && a->b() && a->b()->c()) { a->b()->c()->DoSomething(); }
C++ performs lazy evaluation so this will work. First, a would be evaluated and if it's 0 the whole condition is false so there will be no evaluation of the other parts.
This works for the || operator as well. If you write if (a || b), b won't be evaluated if a is true.
Second one will work provided you want to call only DoSomething().

do {...} while(false)

I was looking at some code by an individual and noticed he seems to have a pattern in his functions:
<return-type> function(<params>)
{
<initialization>
do
{
<main code for function>
}
while(false);
<tidy-up & return>
}
It's not bad, more peculiar (the actual code is fairly neat and unsurprising). It's not something I've seen before and I wondered if anyone can think of any logic behind it - background in a different language perhaps?
You can break out of do{...}while(false).
A lot of people point out that it's often used with break as an awkward way of writing "goto". That's probably true if it's written directly in the function.
In a macro, OTOH, do { something; } while (false) is a convenient way to FORCE a semicolon after the macro invocation, absolutely no other token is allowed to follow.
And another possibility is that there either once was a loop there or iteration is anticipated to be added in the future (e.g. in test-driven development, iteration wasn't needed to pass the tests, but logically it would make sense to loop there if the function needed to be somewhat more general than currently required)
The break as goto is probably the answer, but I will put forward one other idea.
Maybe he wanted to have a locally defined variables and used this construct to get a new scope.
Remember while recent C++ allows for {...} anywhere, this was not always the case.
I've seen it used as a useful pattern when there are many potential exit points for the function, but the same cleanup code is always required regardless of how the function exits.
It can make a tiresome if/else-if tree a lot easier to read, by just having to break whenever an exit point is reached, with the rest of the logic inline afterwards.
This pattern is also useful in languages that don't have a goto statement. Perhaps that's where the original programmer learnt the pattern.
I've seen code like that so you can use break as a goto of sorts.
I think it's more convenient to write break instead of goto end. You don't even have to think up a name for the label which makes the intention clearer: You don't want to jump to a label with a specific name. You want to get out of here.
Also chances are you would need the braces anyway. So this is the do{...}while(false); version:
do {
// code
if (condition) break; // or continue
// more code
} while(false);
And this is the way you would have to express it if you wanted to use goto:
{
// code
if (condition) goto end;
// more code
}
end:
I think the meaning of the first version is much easier to grasp. Also it's easier to write, easier to extend, easier to translate to a language that doesn't support goto, etc.
The most frequently mentioned concern about the use of break is that it's a badly disguised goto. But actually break has more resemblance to return: Both instructions jump out of a block of code which is pretty much structured in comparison to goto. Nevertheless both instructions allow multiple exit points in a block of code which can be confusing sometimes. After all I would try to go for the most clear solution, whatever that is in the specific situation.
This is just a perversion of while to get the sematics of goto tidy-up without using the word goto.
It's bad form because when you use other loops inside the outer while the breaks become ambiguous to the reader. "Is this supposed to goto exit? or is this intended only to break out of the inner loop?"
This trick is used by programmers that are too shy to use an explicit goto in their code. The author of the above code wanted to have the ability to jump directly to the "cleanup and return" point from the middle of the code. But they didn't want to use a label and explicit goto. Instead, they can use a break inside the body of the above "fake" cycle to achieve the same effect.
Several explanations. The first one is general, the second one is specific to C preprocessor macros with parameters:
Flow control
I've seen this used in plain C code. Basically, it's a safer version of goto, as you can break out of it and all memory gets cleaned up properly.
Why would something goto-like be good? Well, if you have code where pretty much every line can return an error, but you need to react to all of them the same way (e.g. by handing the error to your caller after cleaning up), it's usually more readable to avoid an if( error ) { /* cleanup and error string generation and return here */ } as it avoids duplication of clean-up code.
However, in C++ you have exceptions + RAII for exactly this purpose, so I would consider it bad coding style.
Semicolon checking
If you forget the semicolon after a function-like macro invocation, arguments might contract in an undesired way and compile into valid syntax. Imagine the macro
#define PRINT_IF_DEBUGMODE_ON(msg) if( gDebugModeOn ) printf("foo");
That is accidentally called as
if( foo )
PRINT_IF_DEBUGMODE_ON("Hullo\n")
else
doSomethingElse();
The "else" will be considered to be associated with the gDebugModeOn, so when foo is false, the exact reverse of what was intended will happen.
Providing a scope for temporary variables.
Since the do/while has curly braces, temporary variables have a clearly defined scope they can't escape.
Avoiding "possibly unwanted semicolon" warnings
Some macros are only activated in debug builds. You define them like:
#if DEBUG
#define DBG_PRINT_NUM(n) printf("%d\n",n);
#else
#define DBG_PRINT_NUM(n)
#endif
Now if you use this in a release build inside a conditional, it compiles to
if( foo )
;
Many compilers see this as the same as
if( foo );
Which is often written accidentally. So you get a warning. The do{}while(false) hides this from the compiler, and is accepted by it as an indication that you really want to do nothing here.
Avoiding capturing of lines by conditionals
Macro from previous example:
if( foo )
DBG_PRINT_NUM(42)
doSomething();
Now, in a debug build, since we also habitually included the semicolon, this compiles just fine. However, in the release build this suddenly turns into:
if( foo )
doSomething();
Or more clearly formatted
if( foo )
doSomething();
Which is not at all what was intended. Adding a do{ ... }while(false) around the macro turns the missing semicolon into a compile error.
What's that mean for the OP?
In general, you want to use exceptions in C++ for error handling, and templates instead of macros. However, in the very rare case where you still need macros (e.g. when generating class names using token pasting) or are restricted to plain C, this is a useful pattern.
It looks like a C programmer. In C++, automatic variables have destructors which you use to clean up, so there should not be anything needed tidying up before the return. In C, you didn't have this RAII idiom, so if you have common clean up code, you either goto it, or use a once-through loop as above.
Its main disadvantage compared with the C++ idiom is that it will not tidy up if an exception is thrown in the body. C didn't have exceptions, so this wasn't a problem, but it does make it a bad habit in C++.
It is a very common practice. In C. I try to think of it as if you want to lie to yourself in a way "I'm not using a goto". Thinking about it, there would be nothing wrong with a goto used similarly. In fact it would also reduce indentation level.
That said, though, I noticed, very often this do..while loops tend to grow. And then they get ifs and elses inside, rendering the code actually not very readable, let alone testable.
Those do..while are normally intended to do a clean-up. By all means possible I would prefer to use RAII and return early from a short function. On the other hand, C doesn't provide you as much conveniences as C++ does, making a do..while one of the best approaches to do a cleanup.
Maybe it’s used so that break can be used inside to abort the execution of further code at any point:
do {
if (!condition1) break;
some_code;
if (!condition2) break;
some_further_code;
// …
} while(false);
I think this is done to use break or continue statements. Some kind of "goto" code logic.
It's simple: Apparently you can jump out of the fake loop at any time using the break statement. Furthermore, the do block is a separate scope (which could also be achieved with { ... } only).
In such a situation, it might be a better idea to use RAII (objects automatically destructing correctly when the function ends). Another similar construct is the use of goto - yes, I know it's evil, but it can be used to have common cleanup code like so:
<return-type> function(<params>)
{
<initialization>
<main code for function using "goto error;" if something goes wrong>
<tidy-up in success case & return>
error:
<commmon tidy-up actions for error case & return error code or throw exception>
}
(As an aside: The do-while-false construct is used in Lua to come up for the missing continue statement.)
How old was the author?
I ask because I once came across some real-time Fortran code that did that, back in the late 80's. It turns out that is a really good way to simulate threads on an OS that doesn't have them. You just put the entire program (your scheduler) in a loop, and call your "thread" routines" one by one. The thread routines themselves are loops that iterate until one of a number of conditions happen (often one being a certain amount of time has passed). It is "cooperative multitasking", in that it is up to the individual threads to give up the CPU every now and then so the others don't get starved. You can nest the looping subprogram calls to simulate thread priority bands.
Many answerers gave the reason for do{(...)break;}while(false). I would like to complement the picture by yet another real-life example.
In the following code I had to set enumerator operation based on the address pointed to by data pointer. Because a switch-case can be used only on scalar types first I did it inefficiently this way
if (data == &array[o1])
operation = O1;
else if (data == &array[o2])
operation = O2;
else if (data == &array[on])
operation = ON;
Log("operation:",operation);
But since Log() and the rest of code repeats for any chosen value of operation I was wandering how to skip the rest of comparisons when the address has been already discovered. And this is where do{(...)break;}while(false) comes in handy.
do {
if (data == &array[o1]) {
operation = O1;
break;
}
if (data == &array[o2]) {
operation = O2;
break;
}
if (data == &array[on]) {
operation = ON;
break;
}
} while (false);
Log("operation:",operation);
One may wonder why he couldn't do the same with break in an if statement, like:
if (data == &array[o1])
{
operation = O1;
break;
}
else if (...)
break interacts solely with the closest enclosing loop or switch, whether it be a for, while or do .. while type, so unfortunately that won't work.
In addition to the already mentioned 'goto examples', the do ... while (0) idiom is sometimes used in a macro definition to provide for brackets in the definition and still have the compiler work with adding a semi colon to the end of a macro call.
http://groups.google.com/group/comp.soft-sys.ace/browse_thread/thread/52f670f1292f30a4?tvc=2&q=while+(0)
I agree with most posters about the usage as a thinly disguised goto. Macros have also been mentioned as a potential motivation for writing code in the style.
I have also seen this construct used in mixed C/C++ environments as a poor man's exception. The "do {} while(false)" with a "break" can be used to skip to the end of the code block should something that would normally warrant an exception be encountered in the loop.
I have also sen this construct used in shops where the "single return per function" ideology is enforced. Again, this is in lieu of an explicit "goto" - but the motivation is to avoid multiple return points, not to "skip over" code and continue actual execution within that function.
I work with Adobe InDesign SDK, and the InDesign SDK examples have almost every function written like this. It is due to fact that the function are usually really long. Where you need to do QueryInterface(...) to get anything from the application object model. So usually every QueryInterface is followed by if not went well, break.
Many have already stated the similarity between this construct and a goto, and expressed a preference for the goto. Perhaps this person's background included an environment where goto's were strictly forbidden by coding guidelines?
The other reason I can think of is that it decorates the braces, whereas I believe in a newer C++ standard naked braces are not okay (ISO C doesn't like them). Otherwise to quiet a static analyzer like lint.
Not sure why you'd want them, maybe variable scope, or advantage with a debugger.
See Trivial Do While loop, and Braces are Good from C2.
To clarify my terminology (which I believe follows standard usage):
Naked braces:
init();
...
{
c = NULL;
mkwidget(&c);
finishwidget(&c);
}
shutdown();
Empty braces (NOP):
{}
e.g.
while (1)
{} /* Do nothing, endless loop */
Block:
if (finished)
{
closewindows(&windows);
freememory(&cache);
}
which would become
if (finished)
closewindows(&windows);
freememory(&cache);
if the braces are removed, thus altering the flow of execution, not just the scope of local variables. Thus not 'freestanding' or 'naked'.
Naked braces or a block may be used to signify any section of code that might be a potential for an (inline) function that you wish to mark, but not refactor at that time.
It's a contrived way to emulate a GOTO as these two are practically identical:
// NOTE: This is discouraged!
do {
if (someCondition) break;
// some code be here
} while (false);
// more code be here
and:
// NOTE: This is discouraged, too!
if (someCondition) goto marker;
// some code be here
marker:
// more code be here
On the other hand, both of these should really be done with ifs:
if (!someCondition) {
// some code be here
}
// more code be here
Although the nesting can get a bit ugly if you just turn a long string of forward-GOTOs into nested ifs. The real answer is proper refactoring, though, not imitating archaic language constructs.
If you were desperately trying to transliterate an algorithm with GOTOs in it, you could probably do it with this idiom. It's certainly non-standard and a good indicator that you're not adhering closely to the expected idioms of the language, though.
I'm not aware of any C-like language where do/while is an idiomatic solution for anything, actually.
You could probably refactor the whole mess into something more sensible to make it more idiomatic and much more readable.
Some coders prefer to only have a single exit/return from their functions. The use of a dummy do { .... } while(false); allows you to "break out" of the dummy loop once you've finished and still have a single return.
I'm a java coder, so my example would be something like
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class p45
{
static List<String> cakeNames = Arrays.asList("schwarzwald torte", "princess", "icecream");
static Set<Integer> forbidden = Stream.of(0, 2).collect(Collectors.toSet());
public static void main(String[] argv)
{
for (int i = 0; i < 4; i++)
{
System.out.println(String.format("cake(%d)=\"%s\"", i, describeCake(i)));
}
}
static String describeCake(int typeOfCake)
{
String result = "unknown";
do {
// ensure type of cake is valid
if (typeOfCake < 0 || typeOfCake >= cakeNames.size()) break;
if (forbidden.contains(typeOfCake)) {
result = "not for you!!";
break;
}
result = cakeNames.get(typeOfCake);
} while (false);
return result;
}
}
In such cases I use
switch(true) {
case condution1:
...
break;
case condution2:
...
break;
}
This is amusing. There are probably breaks inside the loop as others have said. I would have done it this way :
while(true)
{
<main code for function>
break; // at the end.
}

Do you consider this technique "BAD"?

Sometimes you need to skip execution of part of a method under certain non-critical error conditions. You can use exceptions for that, but exceptions generally are not recommended in normal application logic, only for abnormal situations.
So I do a trick like this:
do
{
bool isGood = true;
.... some code
if(!isGood)
break;
.... some more code
if(!isGood)
break;
.... some more code
} while(false);
..... some other code, which has to be executed.
I use a "fake" loop which will run once, and I can abort it by break or continue.
Some of my colleagues did not like that, and they called it "bad practice". I personally find that approach pretty slick. But what do you think?
Bad practice, it depends.
What I see in this code is a very creative way to write "goto" with less sulphur-smelling keywords.
There are multiple alternatives to this code, which can or can not be better, depending on the situation.
Your do/while solution
Your solution is interesting if you have a lot of code, but will evaluate the "exit" of this processing at some limited points:
do
{
bool isError = false ;
/* some code, perhaps setting isError to true */
if(isError) break ;
/* some code, perhaps setting isError to true */
if(isError) break ;
/* some code, perhaps setting isError to true */
}
while(false) ;
// some other code
The problem is that you can't easily use your "if(isError) break ;" is a loop, because it will only exit the inner loop, not your do/while block.
And of course, if the failure is inside another function, the function must return some kind of error code, and your code must not forget to interpret the error code correctly.
I won't discuss alternatives using ifs or even nested ifs because, after some thinking, I find them inferior solutions than your own for your problem.
Calling a goto a... goto
Perhaps you should put clearly on the table the fact you're using a goto, and document the reasons you choose this solution over another.
At least, it will show something could be wrong with the code, and prompt reviewers to validate or invalidate your solution.
You must still open a block, and instead of breaking, use a goto.
{
// etc.
if(/*some failure condition*/) goto MY_EXIT ;
// etc.
while(/* etc.*/)
{
// etc.
for(/* etc.*/)
{
// etc.
if(/*some failure condition*/) goto MY_EXIT ;
// etc.
}
// etc.
if(/*some failure condition*/) goto MY_EXIT ;
// etc.
}
// etc.
}
MY_EXIT:
// some other code
This way, as you exit the block through the goto, there is no way for you to bypass some object constructor with the goto (which is forbidden by C++).
This problem solves the process exiting from nested loops problem (and using goto to exit nested loops is an example given by B. Stroustrup as a valid use of goto), but it won't solve the fact some functions calls could fail and be ignored (because someone failed to test correctly their return code, if any).
Of course, now, you can exit your process from multiple points, from multiple loop nesting depth, so if it is a problem...
try/catch
If the code is not supposed to fail (so, failure is exceptional), or even if the code structure can fail, but is overly complex to exit, then the following approach could be clearer:
try
{
// All your code
// You can throw the moment something fails
// Note that you can call functions, use reccursion,
// have multiple loops, etc. it won't change
// anything: If you want to exit the process,
// then throw a MyExitProcessException exception.
if(/* etc. */)
{
// etc.
while(/* etc.*/)
{
// etc.
for(/* etc.*/)
{
// etc.
if(/*some failure condition*/) throw MyExitProcessException() ;
// etc.
}
// etc.
callSomeFunction() ;
// the function will throw if the condition is met
// so no need to test a return code
// etc.
}
// etc.
}
// etc.
}
catch(const MyExitProcessException & e)
{
// To avoid catching other exceptions, you should
// define a "MyExitProcessException" exception
}
// some other code
If some condition in the code above, or inside some functions called by the code above, is not met, then throw an exception.
This is somewhat weightier than your do/while solution, but has the same advantages, and can even abort the processing from inside loops or from inside called functions.
Discussion
Your need seems to come from the fact you can have a complex process to execute (code, functions calls, loops, etc.), but you want to interrupt it over some condition (probably either failure, or because it succeeded sooner than excepted). If you can rewrite it in a different way, you should do it. But perhaps, there is no other way.
Let's assume that.
If you can code it with a try/catch, do it: To interrupt a complex piece of code, throwing an exception is the right solution (the fact you can add failure/success info inside your exception object should not be underestimated). You will have a clearer code after that.
Now, if you're in a speed bottleneck, resolving your problem with thrown exceptions as an exit is not the fastest way to do it.
No one can deny your solution is a glorified goto. There won't be a goto-spaghetti code, because the do/while won't let you do that, but it is still a semantic goto. This can be the reasons some could find this code "bad": They smell the goto without finding its keyword clearly.
In this case (and in this performance, profiled-verified) case only, your solution seems Ok, and better than the alternative using if), but of lesser quality (IMHO) than the goto solution which at least, doesn't hide itself behind a false loop.
Conclusion
As far as I am concerned, I find your solution creative, but I would stick to the thrown exception solution.
So, in order of preference:
Use try/catch
Use goto
Use your do/while loop
Use ifs/nested ifs
You're pretty much just disguising a "goto" as a fake loop. Whether you like gotos or not, you'd be just as far ahead using a real undisguised goto.
Personally, I'd just write it as
bool isGood = true;
.... some code
if(isGood)
{
.... some more code
}
if(isGood)
{
.... some more code
}
Why use a fake loop? You can do the same thing with a method and it probably won't be considered a "bad practice" as it is more expected.
someMethod()
{
.... some code
if(!isGood)
return;
.... some more code
if(!isGood)
return;
.... some more code
}
You have complicated non-linear control flow inside a difficult to recognize idiom. So, yes, I think this technique is bad.
It might be worthwhile to spend sometime trying to figure out if this can be written a little nicer.
This is convoluted and confusing, I would scrap it immediately.
Consider this alternative:
private void DoSomething()
{
// some code
if (some condition)
{
return;
}
// some more code
if (some other condition)
{
return;
}
// yet more code
}
Also consider breaking up the code above into more than one method.
public bool Method1(){ ... }
public bool Method2(){ ... }
public void DoStuff(){
bool everythingWorked = Method1() && Method2();
... stuff you want executed always ...
}
The reason why this works is due to something called short circuit logic. Method2 won't be called if Method1 returns false.
This also has the additional benefit that you can break your method into smaller chunks, which will be easier to unit test.
What you're trying to do is non-local failure recovery. This is what goto is for. Use it. (actually, this is what exception handling is for -- but if you can't use that, 'goto' or 'setjmp/longjmp' are the next best thing).
This pattern, the if(succeeded(..)) pattern, and 'goto cleanup', all 3 are semantically and structurally equivalent. Use whichever one is most common in your code project. There's much value in consistency.
I would caution against if(failed(..)) break; on one point in that you're producing a surprising result should you try to nest loops:
do{
bool isGood = true;
.... some code
if(!isGood)
break;
.... some more code
for(....){
if(!isGood)
break; // <-- OOPS, this will exit the 'for' loop, which
// probably isn't what the author intended
.... some more code
}
} while(false);
..... some other code, which has to be executed.
Neither goto cleanup nor if(succeeded(..)) have this surprise, so I'd encourage using one of these two instead.
Basically you just described goto. I use goto in C all the time. I don't consider it bad, unless you use it to emulate a loop (never ever do that!). My typical usage of goto in C is to emulate exceptions (C has no exceptions):
// Code
if (bad_thing_happened) goto catch;
// More code
if (bad_thing_happened) goto catch;
// Even more code
finally:
// This code is executed in any case
// whether we have an exception or not,
// just like finally statement in other
// languages
return whatever;
catch:
// Code to handle bad error condition
// Make sure code tagged for finally
// is executed in any case
goto finally;
Except for the fact that catch and finally have opposite order, I fail to see why this code should be BAD just because it uses goto, if a real try/catch/finally code works exactly like this and just doesn't use goto. That makes no sense. And thus I fail to see why your code should be tagged as BAD.
Refactor. The clean solution will in most cases be to split this code out into a smaller helper function, from which you can return, rather than breaking out of your not-actually-a-loop.
Then you can substitute your break's for return's, and now people can immediately make sense of your code when reading it, instead of having to stop and wonder why you made this loop which doesn't actually loop.
Yes, I'd say that simply because it doesn't behave as the reader would expect, it's a bad practice. The principle of least surprise, and so on. When I see a loop, I expect it to loop, and if it doesn't, I have to stop and wonder why.
I have no problem with that as long as the code is readable.
I have used this idiom for years. I find it preferable to the similar nested or serial ifs , the "goto onError", or having multiple returns. The above example with the nested loop is something to watch out for. I always add a comment on the "do" to make it clear to anyone new to the idiom.
For better or worse, I have used the construct in a few places. The start of it is clearly documented, though:
/* This is a one-cycle loop that simplifies error handling */
do
{
...modestly complex code, including a nested loop...
} while (0);
This is in C, rather than C++ - so exceptions aren't an option. If I were using C++, I would consider seriously using exceptions to handle exceptions. The repeated test idiom suggested by Jeremy is also reasonable; I have used that more frequently. RAII would help me greatly, too; sadly, C does not support that easily. And using more functions would help. Handling breaks from inside the nested loop is done by repeated test.
I would not classify it as a great style; I would not automatically categorize it as "BAD".
It depends on what the alternatives are. You have to admit that the code you posted is somewhat ugly. I wouldn't say it's clear. It's a kind of a hack. So if using some other coding solution would be worse, then ok. But if you have better alternative, don't let the excuse "it's good enough" comfort you.
Its a very strange idiom. It uses a loop for something its not intended and may cause confusion. I'd imagine this is going to span more than one page, and it would be a surprise to most people that this is never run more than once.
How about using more usual language features like functions?
bool success = someSensibleFunctionName();
if(success)
{
...
}
someCommonCodeInAnotherFunction();
I would consider this bad practice. I think it would be more idiomatic, and generally clearer if you made this a function and changed the breaks to returns.
Split your code into smaller chunks of functional elements - so you could split the above into a function that returns instead of breaking.
I don't know if the above is bad practice but it's readability is a little off and may be confusing to others who might have to maintain the source.
To me what you are doing is bad in so many ways. The loop can be replaced by putting that code in a method.
I personally believe that if you have to put a ! in front of your conditions then you are looking for the wrong thing. For readability make your boolean match what you are checking for. You are really checking if there is an error or some bad condition, so I would prefer:
If (isError)
{
//Do whatever you need to do for the error and
return;
}
over
If (!isGood)
{
//Do something
}
So check for what you really want to check for and keep the exception checks to a minimum. Your goal should be readibility over being tricky. Think of the poor soul that is going to have to come along and maintain your code.
One of the first things I worked on 28 years ago was a Fortran program that always needed to check if there was a graphics device available. Someone made the grand decision to call the boolean for this LNOGRAF, so if there was a graphics device available this would be false. I believe it got set this way because of a false efficiency, the check for the device returned zero if there was a graphics device. Throughout the code all the checks were to see if the graphics device was available. It was full of:
If (.NOT. LNOGRAF)
I don't think there was a single:
If (LNOGRAF)
in the program. This was used in mission planning software for B-52's and cruise missiles. It definitely taught me to name my variables for what I'm really checking for.
What about a functional approach?
void method1()
{
... some code
if( condition )
method2();
}
void method2()
{
... some more code
if( condition )
method3();
}
void method3()
{
... yet more code
if( condition )
method4();
}
I would say your solution can be the right solution, but it depends. Paul Tomblin has posted an answer that is better (a series of if tubes) ... if it can be used.
Paul's solution cannot be used when there are expensive object initializations along the way through your loop. If the created objects are used in later steps, the do while (0) solution is better.
That said, variable naming should be improved. Additionally, why reuse the "escape" variable so much? Instead trap each individual error condition explicitly and break the loop so that it is obvious what causes the break out at each point.
Someone else suggested using function calls. Again, this may not be an ideal decomposition if it adds unneeded complexity to the function calls due to the number of args that might be passed at any given step.
Others have suggested this is a difficult to understand idiom. Well, first you could put a comment as suggested at the top of the loop. Second, do-while(0) is a normal and common idiom in macros that all C programmers should recognize immediately, so I just don't buy that.
If your code is doing something other than the plain meaning of the constructs in place, it's a good sign you've ventured into "cute" territory.
In this case you have a "loop" that will only run once. Any reader of the code will need to do a double-take to figure out what's going on.
If the case where it isn't "good" is truly exceptional, then throwing exceptions would be the better choice.
First, if you just want an answer to whether this code structure or idiom is "bad", I would think it is. However, I think this is a symptom of bad decomposition rather than whether the code you have is "good" or "bad".
I would think much better analysis and refactoring will have to be done to be able to further address the source of the problem, rather than looking just at the code. If you can do something like:
if (condition1(...) && condition2(...) && condition3(...) && ... && conditionN(...)) {
// code that ought to run after all conditions
};
// code that ought to run whether all conditions are met or not
Then I think it would be more "readable" and more idiomatic. This way, you can make functions like:
bool conditionN(...) {
if (!real_condition) return false;
// code that ought to run
return true;
};
You get the benefit of better decomposition and help from the compiler to produce the necessary short-circuitry that &&'s will bring. The compiler might even in-line the code in the functions to produce better code than if you would doing the hand-coded loop.
You can use exceptions for that, but exceptions generally are not recommended in normal application logic, only for abnormal situations.
Nothing's wrong with using exceptions. Exceptions are part of application logic. The guideline about exceptions is that they should be relatively rare at run time.
I think that there is nothing basically wrong with the technique. I think that I would make sure that the bool is named something more descriptive than isGood. Although, now that I look at it, why would it not work to put all the code that is in the loop into a single if(!isGood) block? The loop only executes once.
If splitting code between if(!isGood) break; into separate functions, one can end up with dozens of functions containing of just a couple of lines, so that doers not simplify anything. I could not use return because I am not ready to leave the function, there is still stuf I want to do there.
I accept that probably I should just settle for separate if(isGood) {...} condition for every code part which I want to execute, but sometimes that would lead to A LOT of curly braces. But I guess I accept that people does not really like that type of construction, so conditions for everything winds! Thanks for your answers.
A meta comment:
When you're coding, your goal should be clear, maintainable code first. You should not give up legibility on the altar of efficiency unless you profile and prove that it is necessary and that it actually improves things. Jedi mind tricks should be avoided. Always think that the next guy to maintain your code is a big mean psychopath with your home address. Me, for instance.
I think I'd have to agree with your colleagues just because of readability, it's not clear atfirst glance what you are trying to accomplish with this code.
Why not just use
if(isGood)
{
...Execute more code
}
?
I think people aren't being honest here.
If I, as your team lead, would see code like this you'd be up for a little one on one, and flagged as a potential problem for the team as that piece of code is particularly horrid.
I say you should listen to your colleagues and rewrite it following any of the suggestions posted here.
This is what exceptions are for. You can't continue the logic because something went wrong. Even if recovery is trivial, it is still an exception. If you have a really good reason for not using exceptions, such as when you program in a language that does not support them, then use conditional blocks, not loops.