Say you have the following forloop*:

for (int i = 0; i < 10; ++i) {
    // ...

which it could commonly also be written as:

for (int i = 0; i != 10; ++i) {
    // ...

The end results are the same, so are there any real arguments for using one over the other? Personally I use the former in case i for some reason goes haywire and skips the value 10.

* Excuse the usage of magic numbers, but it's just an example.

  • 18
    The superior solution to either of those is to use the arrow operator: int i = 10; while(i --> 0) { /* stuff */ }
    – corsiKa
    Apr 25, 2011 at 17:11
  • @glowcoder the arrow operator is my favorite Apr 25, 2011 at 17:15
  • 3
    @glowcoder, nice but it traverses from the back. You may not always want that.
    – user1249
    Apr 25, 2011 at 17:49
  • 2
    @SuperElectric, it parses like while ((i--) > 0) Apr 25, 2011 at 18:53
  • 17
    There is a (probably apocryphal) story about an industrial accident caused by a while loop testing for a sensor input being != MAX_TEMP. Unfortunately one day the sensor input went from being less than MAX_TEMP to greater than MAX_TEMP without every passing through MAX_TEMP. The process overheated without being detected, and a fire ensued. Sometimes there is a difference between != and <. Apr 26, 2011 at 0:34

9 Answers 9


The reason to choose one or the other is because of intent and as a result of this, it increases readability.

Intent: the loop should run for as long as i is smaller than 10, not for as long as i is not equal to 10. Even though the latter may be the same in this particular case, it's not what you mean, so it shouldn't be written like that.

Readability: a result of writing down what you mean is that it's also easier to understand. For example, if you use i != 10, someone reading the code may wonder whether inside the loop there is some way i could become bigger than 10 and that the loop should continue (btw: it's bad style to mess with the iterator somewhere else than in the head of the for-statement, but that doesn't mean people don't do it and as a result maintainers expect it).

  • 4
    No, the loop should not run as long as i is “smaller than 10”, it should run as long as the (in this case) upper bound is not reached. When using the C++ interval / iterator range rationale, it’s far more logical to express this via != than <. Apr 25, 2011 at 11:34
  • 14
    @Konrad I don't disagree with that at all. The main point is not to be dogmatic, but rather to choose the construct that best expresses the intent of the condition. And so, if you choose to loop through something starting at 0 and moving up, then < actually expresses that precisely.
    – Deckard
    Apr 25, 2011 at 11:36
  • 6
    @Konrad, you're missing the point. The increment operator in this loop makes it obvious that the loop condition is an upper bound, not an identity comparison. If you were decrementing, it'd be a lower bound. If you're iterating over a non-ordered collection, then identity might be the right condition. Apr 25, 2011 at 15:56
  • 3
    @Alex the increment wasn’t my point. An interval doesn’t even necessarily have an order. It just iterates over … well, something until it reaches the end. For example, elements in a hash set. In C++, this is done using iterators and a for loop. Using < here would be silly. Also, Deckard seems to acknowledge that. I very much agree with his comment in response to mine. Apr 25, 2011 at 16:04
  • 1
    Note, if you use a rotary buffer with chase pointers, you MUST use !=
    – SF.
    Jul 28, 2011 at 7:19

The < pattern is generally usable even if the increment happens not to be 1 exactly.

This allows for a single common way to do loops regardless of how it is actually done.

  • 6
    It also allows i to modified inside the loop totally safely if need be. Apr 25, 2011 at 13:10
  • 1
    or if 'i' is modified totally unsafely... Another team had a weird server problem. It kept reporting 100% CPU usage and it must be a problem with the server or the monitoring system, right? No, I found a loop condition written by a 'expert senior programmer' with the same problem we're talking about.
    – jqa
    Apr 25, 2011 at 14:09
  • 13
    Except that not all C++ for loops can use <, such as iterators over a sequence, and so != would be a single common way to do loops in C++. Apr 25, 2011 at 15:01
  • @SnOrfus: I'm not quite parsing that comment. You won't in general reliably get exceptions for incrementing an iterator too much (although there are more specific situations where you will). Apr 25, 2011 at 17:00
  • Well, I follow the < pattern because it requires one keystroke instead of two with the > pattern, and four with !=. It's a matter of OCD-like efficiency really.
    – Spoike
    Aug 17, 2011 at 8:17

In C++ the recommendation by Scott Myers in More Effective C++ (item 6) is always to use the second unless you have a reason not to because it means that you have the same syntax for iterator and integer indexes so you can swap seamlessly between int and iterator without any change in syntax.

In other languages this does not apply so I guess < is probably preferable because of Thorbjørn Ravn Andersen's point.

By the way, the other day I was discussing this with another developer and he said the reason to prefer < over != is because i might accidentally increment by more than one, and that might cause the break condition not to be met; that is IMO a load of nonsense.

  • 17
    "load of nonsense"... until the day you accidentially have an extra i++ in the body of the loop.
    – user1249
    Apr 25, 2011 at 10:13
  • 3
    +1, especially for “load of nonsense”, because it is. If the loop body accidentally increments the counter, you have far bigger problems. Apr 25, 2011 at 11:32
  • 12
    @B Tyler, we are only human, and bigger mistakes have happened before. Consider < to be more defensive programming than != then...
    – user1249
    Apr 25, 2011 at 12:03
  • 2
    @Thorbjørn Ravn Andersen - I'm not saying that I don't agree with you, I do; < is more defensive and my colleagues hate it if I write != so I don't. However, there is a case for != in C++ and that is what I've presented.
    – user23157
    Apr 25, 2011 at 12:48
  • 9
    One scenario where one can end up with an accidental extra i++ is when changing a while loop into a for loop. Not sure that having half the number of iterations is any better than a (near-)infinite loop though; the latter would probably make the bug more obvious.
    – ak2
    Apr 25, 2011 at 13:33

Using (i < 10) is in my opinion a safer practice. It catches the maximum number of potential quitting cases--everything that is greater than or equal to 10. Contrast this with the other case (i != 10); it only catches one possible quitting case--when i is exactly 10.

A byproduct of this is that it improves readability. Additionally, should the increment be anything other 1, it can help minimize the likelihood of a problem should we make a mistake when writing the quitting case.


1) for (i = 1; i < 14; i+=2)

2) for (i = 1; i != 14; i+=2)

Although both cases are likely flawed/wrong, the second is likely to be MORE wrong as it will not quit. The first case will quit, and there is a higher chance that it will quit at the right spot, even though 14 is probably the wrong number (15 would probably be better).

  • The first case may be right! If you want to iterate over all natural numbers less than 14, then there's no better way to to express it - calculating the "proper" upper bound (13) would be plain stupid.
    – maaartinus
    Apr 25, 2011 at 19:52

Here's another answer that no one seems to have come up with yet. for loops should be used when you need to iterate over a sequence. Using != is the most concise method of stating the terminating condition for the loop. However, using a less restrictive operator is a very common defensive programming idiom. For integers it doesn't matter - it is just a personal choice without a more specific example. Looping over collections with iterators you want to use != for the reasons that others have stated. If you consider sequences of float or double, then you want to avoid != at all costs.

What I wanted to point out is that for is used when you need to iterate over a sequence. The generated sequence has a starting point, an interval, and a terminating condition. These are concisely specified within the for statement. If you find yourself either (1) not including the step portion of the for or (2) specifying something like true as the guard condition, then you should not be using a for loop!

The while loop is used to continue processing while a specific condition is met. If you are not processing a sequence, then you probably want a while loop instead. The guard condition arguments are similar here, but the decision between a while and a for loop should be a very conscious one. The while loop is under-appreciated in C++ circles IMO.

If you are processing a collection of items (a very common for-loop usage), then you really should use a more specialized method. Unfortunately, std::for_each is pretty painful in C++ for a number of reasons. In many cases separating the body of a for loop in a free-standing function (while somewhat painful) results in a much cleaner solution. When working with collections, consider std::for_each, std::transform, or std::accumulate. The implementation of many algorithms become concise and crystal clear when expressed in this manner. Not to mention that isolating the body of the loop into a separate function/method forces you to concentrate on the algorithm, its input requirements, and results.

If you are using Java, Python, Ruby, or even C++0x, then you should be using a proper collection foreach loop. As C++ compilers implement this feature, a number of for loops will disappear as will these types of discussions.

  • 2
    "However, using a less restrictive operator is a very common defensive programming idiom." This sums it up more or less.
    – James P.
    Apr 25, 2011 at 14:03
  • +1 for discussin the differences in intent with comparison to while, for, and foreach(or language equivilant)
    – Kevin Peno
    Apr 25, 2011 at 15:08
  • Strictly speaking, the while loop is used to continue processing until a specific condition is not met
    – Alnitak
    Apr 16, 2012 at 20:02
  • @Alnitak - D'oh ... I'll fix that :)
    – D.Shawley
    Apr 21, 2012 at 12:10
  • I was confused by the two possible meanings of "less restrictive": it could refer to the operator being lenient in the values it passes (<) or the operator being lenient in the values it fails (!=). Aug 19, 2016 at 6:18

Using "less than" is (usually) semantically correct, you really mean count up until i is no longer less than 10, so "less than" conveys your intentions clearly. Using "not equal" obviously works in virtually call cases, but conveys a slightly different meaning. In some cases this may be what you need but in my experience this has never been the case. If you really did have a case where i might be more or less than 10 but you want to keep looping until it is equal to 10, then that code would really need commenting very clearly, and could probably be better written with some other construct, such as a while loop perhaps.


One reason why I'd favour a less than over a not equals is to act as a guard. In some limited circumstances (bad programming or sanitization) the not equals could be skipped whereas less than would still be in effect.

Here is one example where the lack of a sanitization check has led to odd results: http://www.michaeleisen.org/blog/?p=358


Here is one reason why you might prefer using < rather than !=. If you are using a language which has global variable scoping, what happens if other code modifies i? If you are using < rather than !=, the worst that happens is that the iteration finishes quicker: perhaps some other code increments i by accident, and you skip a few iterations in the for loop. But what happens if you are looping 0 through 10, and the loop gets to 9, and some badly written thread increments i for some weird reason. Then your loop finishes that iteration and increments i so that the value is now 11. As the loop has skipped the exit condition (i never equalled 10) it will now loop infinitely.

It doesn't necessarily have to be particularly freaky threading-and-global-variables type logic that causes this. It might just be that you are writing a loop that needs to backtrack. If you are mutating i inside the loop and you screw your logic up, having it so that it has an upper bound rather than a != is less likely to leave you in an infinite loop.

  • 3
    Of course, this seems like a perfect argument for for-each loops and a more functional programming style in general. But, why would you want to do that when mutable variables are so much more fun?!
    – Tom Morris
    Apr 25, 2011 at 10:04
  • 3
    I don't think that's a terribly good reason. Either way you've got a bug that needs to be found and fixed, but an infinite loop tends to make a bug rather obvious.
    – ak2
    Apr 25, 2011 at 13:37

In the embedded world, especially in noisy environments, you can't count on RAM necessarily behaving as it should. In a conditional (for, while, if) where you compare using '==' or '!=' you always run the risk that your variables skipped that crucial value that terminates the loop--this can have disasterous consequences--Mars Lander level consequences. Using '<' or '>' in the condition provides an extra level of safety to catch the 'unknown unknowns'.

In the original example, if i were inexplicably catapulted to a value much larger than 10, the '<' comparison would catch the error right away and exit the loop, but '!=' would continue to count up until i wrapped around past 0 and back to 10.

  • 2
    Another related variation exists with code like for (i=4; i<length; i++) csum+=dat[i]; where legitimate packets would always have a length of at least four, but one might receive corrupted packets. If different packet types have different length requirements, one may wish to validate the length as part of the processing that's different for each packet type, but validate the checksum as part of the common logic first. If an under-length packet is received, it doesn't really matter whether the checksum computation reports "good" or "bad", but it shouldn't crash.
    – supercat
    Aug 13, 2012 at 18:11

Not the answer you're looking for? Browse other questions tagged or ask your own question.