# I need advice on breaking a bad habit; 'if' & while reliance' (C++)

## Recommended Posts

Hi guys,

I'm starting to notice what I'm calling a problem early on. Whenever I create code I have too much of a tendency to use 'if' and 'while' loops, which I know is bad practice. The problem lies in that I'm still learning the syntax in C++, but at this stage I keep thinking in terms of of 'if' or 'while' which is resulting in needlessly complicated code. Can anyone offer me some advice on how to think outside of these two notions?

##### Share on other sites
Can you maybe give an example of how you think you are misusing the language then we may be able to advise...

##### Share on other sites
[quote name='Walkerism' timestamp='1309178618' post='4828215']
Hi guys,

I'm starting to notice what I'm calling a problem early on. Whenever I create code I have too much of a tendency to use 'if' and 'while' loops, which I know is bad practice. The problem lies in that I'm still learning the syntax in C++, but at this stage I keep thinking in terms of of 'if' or 'while' which is resulting in needlessly complicated code. Can anyone offer me some advice on how to think outside of these two notions?
[/quote]

This kind of optimization is pretty premature. These days compilers are generally smarter than you, so it's better to wait until you have a bottleneck before worrying about optimizing anything.

edit: to clarify I meant optimize anything at this minute a level, not optimize in general.

##### Share on other sites
Where did you hear that this is bad practice?

The only thing I can think of is nested use of loops and conditionals. To write clear code, replace such use by factoring out the logic into helper functions.

##### Share on other sites
[quote name='braindigitalis' timestamp='1309178992' post='4828216']
Can you maybe give an example of how you think you are misusing the language then we may be able to advise...
[/quote]

I'll dig around and try to find a good example, off the top of my head though (and where the concern lies) is I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ). It makes it hard for me to build values that are relevant.

[quote name='way2lazy2care' timestamp='1309179317' post='4828220']This kind of optimization is pretty premature. These days compilers are generally smarter than you, so it's better to wait until you have a bottleneck before worrying about optimizing anything.

[/quote]

That's quite comforting to know thanks, though I must admit I find learning easier when I'm aware of the steps taken ahead. I find enjoyment in being prepared for the road ahead, keeps me enthusiastic throughout the early stages when steps ahead have been made aware.

##### Share on other sites
[quote name='Walkerism' timestamp='1309181163' post='4828228']
I'll dig around and try to find a good example, off the top of my head though (and where the concern lies) is I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ). It makes it hard for me to build values that are relevant.
[/quote]

If you are constantly checking the state of objects it's probably better to store the state and only check it's state when you want to check it.

This is still kind of a vague use case to optimize though. There are plenty of situations where it's perfectly acceptable and others where it may not be necessary. It's very much a case by case thing.

##### Share on other sites
It's certainly not a bad habit or a problem in principle. Branching is one of the key features of this whole computer thing and loops are what you do whenever you want to perform an operation on a large number of entities.

Checking states of things, doing comparisons, validating actions against constraints... [i]This is the work of a computer[/i]. This is its reason for being. It's what game software [i]does[/i].

Nevertheless, I will go over some things, but only after I go over three warnings. As a beginner, the instinct to ignore these warnings will be great. Stamp that instinct into a pit.

1) As a beginner, the number one thing you're learning is the [i]bureaucratics[/i] of putting together game software. Things like how a whole game application fits together, how to use RAD tools to write tools, Model-View-Controller and Observer pattern and so on, how to integrate characters talking into a game loop, crap like that.

2) Optimizations heavily depend on the platform. By the time you've learned the above, the platform will have changed. I just wrote something on the iPad, and almost nothing I learned to make our Java application work well was useful. I referred to manuals provided by Apple to make it perform to spec. Java and iOS each required mountains of esoteric knowledge to make them perform.

Wasting time on platform ideosyncracies will prevent you from doing part 1. It is time wasted.

3) Use a profiler to learn what actually needs to be optimized, because you don't know what is actually challenging the computer.

Now then...

[quote][color="#1C2837"][size="2"]too much of a tendency to use 'if' and 'while' loops, which I know is bad practice[/quote][/size][/color]

[color="#1C2837"][size="2"]In Java (and maybe C#?) it's common practice to use the [i]instanceof[/i] and [i]is[/i] operators to ask [i]what[/i] an object is, and act accordingly.[/size][/color]

[color="#1C2837"][size="2"]There is an equivalent in C++ and it's considered bad practice. (I won't say how you do this, it's complicated.) If you find yourself making such decisions, ask yourself if you could be using a virtual method to accomplish this.[/size][/color]

[quote][color="#1C2837"][size="2"]I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ).[/quote][/size][/color]

[size="3"][color="#1C2837"][size="2"]C++ uses "lazy evaluation". Say I have:[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]if(a && (x > x2) && (y > y2)) ... ;[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]Where 'a' is a boolean.[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]If a is [i]false[/i], than [i]the rest of the statement will not be evaluated[/i]. Why not? Because the AND operator [i]may[/i] only yield true if [i]both[/i] operands are true. As soon as the machine knows that one of them is not true, it quits. Make sense?[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]So you follow, as a habit, the "common case first" principle. Which piece is most likely to fail? Put that first. It will reduce the likelihood that other segments will be evaluated superfluously. If you can't make a prediction, don't order them.[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]Other languages, like Java, do [i]not[/i] use lazy evaluation. (See what I mean about platform?)[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]In some loops you may find that you're repeating an evaluation who's dependent variables do not change from one iteration to the next. [/size][/color][/size][color="#1C2837"][size="2"]You can use the bool datatype to perform an [i]store[/i] an evaluation.[/size][/color]

[size="3"][color="#1C2837"][size="2"]But just to reiterate, checking these things is literally what you're supposed to be doing. If you need to do a bounds check, do a bounds check.[/size][/color][/size]

[size="3"][color="#1C2837"][size="2"]If you're worried you might be doing this dozens of times... Try to realize that a typical game is running hundreds of thousands of vertices through all kinds of 4x4 matrix-vector multiplications and rasterizing a million+ pixels using custom "shader" software [i]every frame.[/i] As a beginner, you do not have the art resources to make even the cheapest computer break a sweat.[/size][/color][/size]

##### Share on other sites
I haven't found any code where there were more while' statements than I would have liked. However, having lots of if' statements if often a problem. Not because the code generated would be slow (that argument would certainly be a premature optimization, and besides it's probably not true), but because code without if's is easier to read, easier to test and easier to maintain.

[url="http://www.youtube.com/watch?v=4F72VULWFvc"]This Google talk[/url] is about coding without if's. I highly recommend listening to it, even if you don't follow its advice. It will give you some good ideas on how to organize and test code.

##### Share on other sites
[quote name='JoeCooper' timestamp='1309186584' post='4828266'][size="3"][color="#1C2837"][size="2"]As a beginner, you do not have the art resources to make even the cheapest computer break a sweat.[/size][/color][/size]
[/quote]

Open Blender3D -> Add Monkey -> Subsurf to level >100 -> convert to mesh -> blow up computer (I'm sure the computer would blow up as soon as you try to subsurf that much)

;)

Just playing devils advocate. I agree with everything you've said.

##### Share on other sites
lolz, I know. Or even better: while(1) fork();

##### Share on other sites
JoeCooper's advice is good. I just wanted to point out the following:
[quote]
Other languages, like Java, do not use lazy evaluation. (See what I mean about platform?)
[/quote]
What you are describing is most commonly called "short circuit evaluation". The term "lazy evaluation" is more often used in functional languages to mean expressions which are evaluated as late as possible, even allowing potentially infinite expressions to be described, so long as you are careful never to try and fully evaluate it. A classic example is a list of Fibonacci numbers, the expression is lazy such that a particular element can be evaluated, but you shouldn't try to do something like get the length of this list.

Java does use short-circuit evaluation on the operators &&, ||. According to [url="http://en.wikipedia.org/wiki/Short-circuit_evaluation"]the table in this article[/url], all the mainstream languages that offer operators like &&, || do short-circuit evaluation on them.

This is a common idiom in Java (and most such languages), that avoids accessing an invalid object:
[code]
if(object != null && object.someCondition())
{
// ...
}
[/code]

##### Share on other sites
Crickey! I was 99% sure I looked it up and I've written a few apps assuming it didn't work that way. I've got code like

[code]if(object != null)
if(...)
{
...
};[/code]

Everywhere.

Must've been cause I got the term wrong. Thanks for the note about that!

##### Share on other sites
[quote name='rip-off' timestamp='1309189277' post='4828289']
all the mainstream languages that offer operators like &&, || do short-circuit evaluation on them.
[/quote]
Assuming that they aren't overloaded anyways. In C++ if you overload && or || then short circuit evaluation no longer applies. Some languages don't allow operator overloading on logical and and logical or for this reason.

##### Share on other sites
There is something to look out for though if you feel like you're being too reliant on conditional statements. Make sure your code is separated into neat routines that only address a single task and Don't Repeat Yourself (aka the dry principal). So, if you have massive routines with lines and lines of code with many many branches of possible execution you are quite probably violating the DRY principal and should refactor. It makes your code more readable and maintainable and all that jazz and even more performant a lot of times as you likely won't need as many clock cycles to get through your various branches to execute the code you need to. All the above advice is good. This is just an important aside.

##### Share on other sites
[quote]
Assuming that they aren't overloaded anyways.
[/quote]
I would hope not, not for such operators anyway! Good catch though.

##### Share on other sites
[quote name='Walkerism' timestamp='1309181163' post='4828228']
I'll dig around and try to find a good example, off the top of my head though (and where the concern lies) is I'm essentially checking the state of various entities within my game with rather large search criteria (i.e if( bool==true && x<y && y.x>x &&... ) in order to work with boolean values, which again will lead to the likes of if( coll== true ). It makes it hard for me to build values that are relevant.
[/quote]
I think you're probably not using functions enough.

I don't too often write if statements that compound that many checks together, but that doesn't mean my code isn't checking for all the same things yours is. My code is just structured more like this:
[code]
void main()
{
if (someBool == true)
{
Func1();
}
}

void Fun1()
{
if (someThing.x > x && someThing.y > y)
{
Func2();
}
else
{
Func3();
}
}
[/code]

Just try to write small functions which perform individual tasks. A function should be in charge of doing only one thing, and should usually be small (it should fit entirely on your screen).

##### Share on other sites
[quote name='rip-off' timestamp='1309189277' post='4828289']
This is a common idiom in Java (and most such languages), that avoids accessing an invalid object:
[code]
if(object != null && object.someCondition())
{
// ...
}
[/code]
[/quote]

Interesting factoid from the google talk. To avoid this situation, you should return a null object rather than a null reference to avoid having to do this check. Not sure on the performance impact of this as I have literally just heard it in the google talk, but it seems like solid advice to me.

##### Share on other sites
I have to say guys, this is honestly some of the most informative and helpful advice I've read since I started programming. Seriously, you've given me much to think about and put a lot of ideas to rest. I'll start to think in functions to make my code more approachable. As for optimizing, I'll keep brush that worry aside XD

Cheers everyone, I'll be coming back to this thread often to make sure my code doesn't disagree with the guidelines you've collectively written.

##### Share on other sites
Oh yeah, and don't actually run the while(1) fork(); code I mentioned earlier, ever.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628345
• Total Posts
2982200

• 9
• 9
• 24
• 10
• 9