0

Given a vector v, I want to loop through each element in the vector and perform an operation that requires the current index.

I've seen a basic for loop written both of these ways:

// Using "<" in the terminating condition
for (auto i = 0; i < v.size(); ++i)
{
    // Do something with v[i]
}

// Using "!=" in the terminating condition
for (auto i = 0; i != v.size(); ++i)
{
    // Do something with v[i]
}

Is there any practical reason to prefer one over the other? I've seen it written using < much more often, but is there a performance benefit to using !=?

tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • 4
    In this particular case, they are both the same. And the use of `auto` in both is wrong, since `size()` returns an unsigned integer, usually a `size_t`, whereas the type deduced from `0` is `int` instead. You shouldn't loop through a `size_t`-based container using an `int` for the indexing, you want `size_t` instead (or better, `vector::size_type`). Or better, don't use indexes at all, use iterators, or a [range-based `for` loop](https://en.cppreference.com/w/cpp/language/range-for) – Remy Lebeau Oct 21 '20 at 01:18
  • 2
    In actual CPUs, there's usually only one instruction for comparing values (used for `<` and `!=`), and the conditional branch instructions (that differ by the comparison performed) are usually of equal cost no matter which condition they're based on. For a user-defined type with overloaded `!=` and `<`, it might matter (typically `!=` would be cheaper); for primitives, it almost certainly won't. – ShadowRanger Oct 21 '20 at 01:22
  • The `!=` form more closely matches the idiom used with iterators. – Mark Ransom Oct 21 '20 at 01:23
  • 1
    Because `vector` has random access, using `<` is fine, but for something like `list` you can only use `!=`, so you can create more generic code and it's easier to switch types by using `!=` but that doesn't necessarily mean it should be used instead – Tas Oct 21 '20 at 01:26
  • 1
    @ShadowRanger on most RISC architectures without flags like MIPS or RISC-V you'll need 2 instructions to compare `<` but only one for `!=`. See [If greater than or equal in MIPS](https://stackoverflow.com/a/25860371/995714), [Why isn't MIPS BLT instruction implemented in hardware?](https://stackoverflow.com/q/19923977/995714) – phuclv Oct 21 '20 at 02:16
  • 2
    Some people use `<` because it’s more reliable if the code does anything other than simply increment the index once on each iteration of the loop. – Pete Becker Oct 21 '20 at 02:49
  • @RemyLebeau What you said about `auto` is a great point. I didn't even think of that! In my case I probably will never have an issue caused by it but I will try to fix it anyway because it is good practice. – tjwrona1992 Oct 21 '20 at 17:00

3 Answers3

1

There is one, albeit kinda convoluted, reason to prefer < over !=.

If for whatever reason the body of your lop modifies i and skips over the threshold, < still terminates the loop, where != will keep iterating.

It might make no difference in the vast majority of cases, but getting used to < might prevent bugs that != won't. There's also an additional advantage, that is ridiculously minor but < takes less characters to write, so it makes the source file smaller.

Again the above argument is borderline a joke, but if you need an argument to use one over the other, there you have it.

Makogan
  • 8,208
  • 7
  • 44
  • 112
0

You should probably prefer using a range-for instead.

Is there any practical reason to prefer one over the other?

There are no strong reasons to prefer one way or another given that both have equivalent behaviour.

Using the less than operator works even if the end condition is not one of the values of the accumulator which would be possible if increment was greater than 1 or the initial value was greater than the end condition. As such, it is more general, which means that using it always may be more consistent. Consistency is a weak argument, but a weak argument is better than no argument if you agree with it.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

There is no difference in performance.

There is a huge difference if you decided to change ++i in such a way that the loop would step over the desired end.

For clarity for other programmers reading your code, use the convention they expect to see, namely <. When I see i != ..., I think "he is skipping over that one value".

The is an obscure bug with < -- Suppose you iterating over all 256 chars using a byte-sized i. The value will overflow and probably never show the value 256. The loop will never stop. And != won't fix the bug.

Rick James
  • 135,179
  • 13
  • 127
  • 222