Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Playing around with for arguments

Tags:

c++

Inspired by this.

Suppose we have a non empty std::vector<T> v; is there any difference between

for (int i = v.size() - 1; i >= 0; i--) {
///Stuff.
}

and:

for (int i = v.size(); i--; ) {
///Stuff.
}

?

I mean, I wouldn't do that for readability sake, but who knows what could be useful in life...

(Here just a test to see they are equivalent)

Edit: The point is having i as index to access backward the vector (in a case where having the index was preferable to having iterators)

Edit 2: Out of curiosity: They end up having slightly different assembly code. See this and this.

like image 723
Antonio Avatar asked Aug 19 '13 01:08

Antonio


2 Answers

One could think of a for loop

for (<decl-init> ; <condition> ; <post-adjust>) <body>

as a rough equivalent to this while loop:

<decl-init>;
while (condition) {
    <body>;
    <post-adjust>;
}

The biggest difference between the for and the rewrite above is the scope of variables declared in the <decl-init> block, but this is not important for the analysis below.

Rewriting both loops as a while loop gives you this:

int i = v.size() - 1;
while ( i >= 0 ) {
    <body>;
    i--;
}

vs.

int i = v.size(); 
while (i--) {
    <body>;
}

As you can see, the only difference is that i is decremented before entering the iteration, and the condition is started with i greater by 1 than in the first loop. These two adjustments "cancel each other", making your loops equivalent from the technical point of view. Aesthetics is a different thing, though: conditions with side effects are harder to understand than "pure" ones, so the first loop is more readable.

like image 53
Sergey Kalinichenko Avatar answered Sep 28 '22 12:09

Sergey Kalinichenko


It is a legal way of doing it, but using i-- as a condition in a for loop is a terrible idea in terms of readability.

The for loop is meant to consist of 3 parts - why make people lives harder?

People who read your code will be happy if you stick to the traditional for loop:

for (int i = v.size() - 1; i >= 0; i--) {
    ///Stuff.
}
like image 25
Oleksiy Avatar answered Sep 28 '22 10:09

Oleksiy