Using nested if statements to structure code - c++

I'm trying to structure my code in a readable way. I've read that one way of doing it is as follows:
if(Init1() == TRUE)
{
if(Init2() == TRUE)
{
if(Init3() == TRUE)
{
...
Free3();
}
Free2();
}
Free1();
}
I like this way of doing things, because it keeps each FreeX inside its matching InitX loop, but if the nesting goes beyond three levels it quickly becomes unreadable and goes way beyond 80 columns. Many functions can be broken up into multiple functions so that this doesn't happen, but it seems dumb to break up a function just to avoid too many levels of nesting. In particular, consider a function that does the initialization for a whole class, where that initialization requires ten or more function calls. That's ten or more levels of nesting.
I'm sure I'm overthinking this, but is there something fundamental I'm missing in the above? Can deep nesting be done in a readable way? Or else restructured somehow whilst keeping each FreeX inside its own InitX loop?
By the way, I realise that the above code can be compacted to if(Init1() && Init2()..., but the code is just an example. There would be other code between each InitX call that would prevent such a compaction.

Since you included the C++ tag, you should be using RAII - Resource Acquisition Is Initialization. There's a bunch of good online resources explaining this concept, and it will make a lot of things pertaining to resource management a lot easier.

I'm sure I'm overthinking this, but is there something fundamental I'm missing in the above? [...] Or else restructured somehow whilst keeping each FreeX inside its own InitX loop?
Yes. This is a textbook case of code that will benefit enormously from RAII code:
instead of the construct:
if(init(3) == TRUE)
{
free3();
}
consider this:
raii_resource3 r3 = init3(); // throws exception if init3 fails
// free3 called internally
// by raii_resource3::~raii_resource3
Your full code becomes:
raii_resource1 r1 = init1();
raii_resource2 r2 = init2();
raii_resource3 r3 = init3();
You will have no nested ifs, your code will be clear and straightforward (and focusing on the positive case).
You will just have to write RAII wrappers for resources 1, 2 and 3.

As others have pointed out, the obvious answer is RAII. But if
the issue of overly deep nesting comes up without RAII, you
should really ask yourself if you aren't making your functions
too complicated. A function should rarely have more than about
ten lines (including such checks). If you look at real cases,
you'll find that it almost always makes more sense to break the
function up. Even with RAII, you should generally only have one
instance of an RAII class per function. (There are exceptions,
of course; arguably, something like std::lock_guard shouldn't
count.)

What i would recommend would be to use a switch statement.
I'm a big fan of switch statements when it comes down to code like this
Hope this helps.
switch (i) {
case 1:
// action 1
break;
case 2:
// action 2
break;
case 3:
// action 3
break;
default:
// action 4
break;
}

You may have heard that gotos are evil, But if you are sticking to c, there is nothing "dirty" about using gotos to handle exceptions like this:
foo()
{
if (!Init1())
goto Error1;
if (!Init2())
goto Error2;
...
...
Error2:
Free2();
Error1:
Free1();
}

Related

is it bad practice to use nesting switch statments in c++?

I've been working on a project in class and the code I have written so far works well. A big part of my code uses nested switch statements. While I'm going to turn it in the way it is now, I would like to know for future reference if nested switch statements are generally frowned upon.
As you've probably noticed, because you asked, they're not exactly the easiest things to follow, so I would generally try to avoid them where possible.
This doesn't mean you can't do that kind of control flow - the trick being to split the cases out into their own functions. This lets someone read the top level switch, comprehend its branches and what happens (because you'll of course have given your functions good, descriptive names), and then they can examine each function in turn to understand the next level if they need to.
To avoid the cost of a function call which would previously have been unnecessary you can mark the functions inline to make the compiler effectively copy the body of the function to the call site.
It'd end up looking something like this incredibly genericised and incomplete skeleton:
int main() {
int thing;
char second_level_thing;
// various code which produces thing and second_level_thing
switch (thing) {
case 0: do_zero_case(second_level_thing); break;
case 1: do_one_case(); break;
default: do_default_case(); break;
}
// the rest of main
}
inline void do_zero_case(char second_level_thing) {
switch (second_level_thing) {
case 'a': // 0 -> a branch code
// etc...
}
}
// etc...
Do not call your functions things like do_zero_case! Name them after what it actually does.
I would add that if multiple levels are inspecting the same value there's something very odd going on.
There are also alternative control flows available through use of OOP techniques (virtual method calls in a variety of forms), templates, higher-order functions and so forth. Sometimes a nice simple switch statement or two is exactly what you need though!
Generally speaking, if and switch statements are more "costy" in terms of calculations for the proccessor, because you force the assembler to make new guesses (for what the next instructions will be) every time you jump from case to case. Try to use as less possible if your prime concern is algorithm efficiency.

How do you write the error checking part of a method to make it readable and error prone?

I had a disagreement with another programmer on how to write a method with a lot of error checking:
public void performAction() {
if (test1) {
if (test2) {
if (test3) {
// DO STUFF
} else {
return "error 3";
}
} else {
return "error 2";
}
} else {
return "error 1";
}
}
-
public void performAction() {
if (!test1) {
return "error 1";
}
if (!test2) {
return "error 1";
}
if (!test3) {
return "error 1";
}
// DO STUFF
}
To me, the deep nesting of if statements makes the first example hard to read.
The second one, despite having three returns, is more readable.
I checked by curiosity what Code Complete was saying about that and it left me less sure about the way to handle this:
The stack of error conditions at the bottom of the nest is a sign of well-written error-processing code.
but then
Indenting the main body of the routine inside four if statements is aesthetically ugly, especially if there’s much code inside the innermost if statement.
and considering using guard clauses, as in the second example
Minimize the number of returns in each routine. It’s harder to understand a routine when, reading it at the bottom, you’re unaware of the possibility that it returned some-where above.
How do you write the error checking part of a method to make it readable and error-prone?
Nothing gets programmers into a fight faster than stylistic debates (Is it ever advantageous to use 'goto' in a language that supports loops and functions? If so, why?). So the short answer is "Whatever style you and your team decide is best for your project/language."
That being said, I would like to add my 2 cents to Code Complete's comment about multiple returns. You should make a distinction between multiple successful returns, and multiple returns. If I need to investigate 5 returns that are not due to errors being generated, the function probably needs to be rewritten. If you gracefully exit your function immediately after an error is detected, then a maintenance programmer (i.e. you in 6 months) should have no more trouble following the main logic of your function than if you had nested all of those error checks.
So, my personal opinion is that your second code example is the better choice.
This is my opinion.
The old mantra of "Minimize the number of returns in each routine" seem to be a bit dated. It is highly applicable when you have methods longer 8-10 lines of code, where lots of operations are executed.
The newer schools of thought, emphasizing Single Responsibility and very short methods, would seem to render that a bit unnecessary. When your whole method does not do any operations directly, but simply handles the error processing, multiple returns in a clean format would be best.
In either case, any time you have nested ifs, the readable suffers substantially.
The one optimization I would make is to use an if-else-if structure, to clearly indicate the logic flow.
Sample code:
public void Execute()
{
if (test1)
{
return;
}
else if (test2)
{
return;
}
PerformAction();
}
private void PerformAction()
{
//DO STUFF
}
If you're using a language with exception-handling and automated resource management, your colleagues should probably get used to your preferred style with premature exits in the case of encountering a external input error.
The idea of trying to shift function exits towards the bottom of the scope was useful in the days before exception handling and automated resource management (ex: languages without destructors or GC like C) because error recovery often required manual cleanup.
In those manual cleanup cases, it was often useful to shift the exits towards the bottom of a function so that you could look at the top of the function for the logic creating the temporary resources needed by the function and towards the bottom of the function to see the symmetrical clean up of those resources.
In such cases as with assembly, it's quite common to see jumps/branches to an error label at the bottom of the function where the clean up would occur. It's also not too uncommon even in C using gotos for this purpose.
Also, as mentioned, deep nesting introduces a lot of mental overhead. Your brain has to function like a deeply-nested stack trying to remember where you're at, and as even Linus Torvalds, a diehard C coder, likes to say: if you need something like 4 nested levels of indentation in a single function, your code is already broken and should be refactored (I'm not sure I agree with him about the precise number, but he has a point in terms of how it obfuscates logic).
When you move into a more modern language like C++, you now have automated resource management via destructors. Functions should then no longer be mentioning cleanup details, as the resources should handle the cleanup automatically by conforming to what's called the resource acquisition is initialization idiom (not exactly the best name). That eliminates one of the big reasons to favor a style that strives to have error handling logic towards the bottom.
On top of that, when you use a language like C++, it potentially throws exceptions and all over the place. So it's not uncommon for every other line of code to have the effect of having a hidden, implicit exit with logic like this:
if an exception occurs:
automatically cleanup resources and propagate the error
So there are hidden, premature exits all over the place. So if you use a language like that, not only should you get used to premature exits in the case of an exception, but you're kind of forced into it and have no other choice. As far as readability/traceability is concerned in those languages, you can't get any simpler than:
if something bad happened:
return error
The one exception I'd suggest to the rule is static branch prediction. If you're writing very performance-critical code where the smallest of micro-efficiencies counts more than readability, then you want your branches to be weighted towards favoring the common case line of execution as Intel advises. So instead of:
if something exceptional happened:
return error
... for performance you might invert the logic and do this instead:
if something normal happened:
...
return success
return error

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.
}

Is it a bad practice to use an if-statement without curly braces? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I've seen code like this:
if(statement)
do this;
else
do this;
However, I think this is more readable:
if(statement){
do this;
}else{
do this;
}
Since both methods work, is this simply a matter of preference which to use or would one way be recommended over the other?
The problem with the first version is that if you go back and add a second statement to the if or else clauses without remembering to add the curly braces, your code will break in unexpected and amusing ways.
Maintainability-wise, it's always smarter to use the second form.
EDIT: Ned points this out in the comments, but it's worth linking to here, too, I think. This is not just some ivory-tower hypothetical bullshit: https://www.imperialviolet.org/2014/02/22/applebug.html
One problem with leaving out statement blocks is the else-ambiguity. That is C-inspired languages ignore indentation and so have no way of separating this:
if(one)
if(two)
foo();
else
bar();
From this:
if(one)
if(two)
foo();
else
bar();
My general pattern is that if it fits on one line, I'll do:
if(true) do_something();
If there's an else clause, or if the code I want to execute on true is of significant length, braces all the way:
if(true) {
do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}
if(false) {
do_something();
} else {
do_something_else();
}
Ultimately, it comes down to a subjective issue of style and readability. The general programming world, however, pretty much splits into two parties (for languages that use braces): either use them all the time without exception, or use them all the time with exception. I'm part of the latter group.
The "rule" I follow is this:
If the "if" statement is testing in order to do something (I.E. call functions, configure variables etc.), use braces.
if($test)
{
doSomething();
}
This is because I feel you need to make it clear what functions are being called and where the flow of the program is going, under what conditions. Having the programmer understand exactly what functions are called and what variables are set in this condition is important to helping them understand exactly what your program is doing.
If the "if" statement is testing in order to stop doing something (I.E. flow control within a loop or function), use a single line.
if($test) continue;
if($test) break;
if($test) return;
In this case, what's important to the programmer is discovering quickly what the exceptional cases are where you don't want the code to run, and that is all coverred in $test, not in the execution block.
I am using the code formatter of the IDE I use. That might differ, but it can be setup in the Preferences/Options.
I like this one:
if (statement)
{
// comment to denote in words the case
do this;
// keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
do this;
}
Having the braces right from the first moment should help to prevent you from ever having to debug this:
if (statement)
do this;
else
do this;
do that;
Use braces for all if statements even the simple ones. Or, rewrite a simple if statement to use the ternary operator:
if (someFlag) {
someVar= 'someVal1';
} else {
someVar= 'someVal2';
}
Looks much nicer like this:
someVar= someFlag ? 'someVal1' : 'someVal2';
But only use the ternary operator if you are absolutely sure there's nothing else that needs to go in the if/else blocks!
I prefer using braces. Adding braces makes it easier to read and modify.
Here are some links for the use of braces:
Prefer Multiline if
Omitting Braces: Not Just A Matter Of Style
Stack Overflow
From my experience the only (very) slight advantage of the first form is code readability, the second form adds "noise".
But with modern IDEs and code autogeneration (or autocompletion) I strongly recommend using the second form, you won't spend extra time typing curly braces and you'll avoid some of the most frequent bugs.
There are enough energy consuming bugs, people just shoudn't open doors for big wastes of time.
One of the most important rule to remember when writing code is consistency. Every line of code should be written the same way, no matter who wrote it. Being rigorous prevents bugs from "happening" ;)
This is the same with naming clearly & explicitly your variables, methods, files or with correctly indenting them...
When my students accept this fact, they stop fighting against their own sourcecode and they start to see coding as a really interesting, stimulating and creative activity. They challenge their minds, not their nerves !
Personally I use the first style only throw an exception or return from a method prematurely. Like argument Checking at the beginning of a function, because in these cases, rarely do I have have more than one thing to do, and there is never an else.
Example:
if (argument == null)
throw new ArgumentNullException("argument");
if (argument < 0)
return false;
Otherwise I use the second style.
It is a matter of preference. I personally use both styles, if I am reasonably sure that I won't need to add anymore statements, I use the first style, but if that is possible, I use the second. Since you cannot add anymore statements to the first style, I have heard some people recommend against using it. However, the second method does incur an additional line of code and if you (or your project) uses this kind of coding style, the first method is very much preferred for simple if statements:
if(statement)
{
do this;
}
else
{
do this;
}
However, I think the best solution to this problem is in Python. With the whitespace-based block structure, you don't have two different methods of creating an if statement: you only have one:
if statement:
do this
else:
do this
While that does have the "issue" that you can't use the braces at all, you do gain the benefit that it is no more lines that the first style and it has the power to add more statements.
I have always tried to make my code standard and look as close to the same as possible. This makes it easier for others to read it when they are in charge of updating it. If you do your first example and add a line to it in the middle it will fail.
Won't work:
if(statement)
do this;
and this;
else
do this;
My personal preference is using a mixture of whitespace and brackets like this:
if( statement ) {
// let's do this
} else {
// well that sucks
}
I think this looks clean and makes my code very easy to read and most importantly - debug.
I agree with most answers in the fact that it is better to be explicit in your code and use braces. Personally I would adopt a set of coding standards and ensure that everyone on the team knows them and conforms. Where I work we use coding standards published by IDesign.net for .NET projects.
I prefer putting a curly brace. But sometimes, ternary operator helps.
In stead of :
int x = 0;
if (condition) {
x = 30;
} else {
x = 10;
}
One should simply do : int x = condition ? 30 : 20;
Also imagine a case :
if (condition)
x = 30;
else if (condition1)
x = 10;
else if (condition2)
x = 20;
It would be much better if you put the curly brace in.

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.