Never seen before C++ for loop

I was converting a C++ algorithm to C#. I came across this for loop:

for (u = b.size(), v = b.back(); u--; v = p[v]) 
b[u] = v;

It gives no error in C++, but it does in C# (cannot convert int to bool). I really can't figure out this for loop, where is the condition?

Can someone please explain?

PS. Just to check, to adapt a VECTOR to a LIST does b.back() correspond to b[b.Count-1] ?


Solution 1:

The condition of the for loop is in the middle - between the two semicolons ;.

In C++ it is OK to put almost any expression as a condition: anything that evaluates to zero means false; non-zero means true.

In your case, the condition is u--: when you convert to C#, simply add != 0:

for (u = b.size(), v = b.back(); u-- != 0; v = p[v]) 
    b[u] = v; //                     ^^^^ HERE

Solution 2:

Lots of accurate answers, but I think it's worth writing out the equivalent while loop.

for (u = b.size(), v = b.back(); u--; v = p[v]) 
   b[u] = v;

Is equivalent to:

u = b.size();
v = b.back();
while(u--) {
   b[u] = v;
   v = p[v];
}

You might consider refactoring to the while() format as you translate to C#. In my opinion it is clearer, less of a trap for new programmers, and equally efficient.

As others have pointed out -- but to make my answer complete -- to make it work in C# you would need to change while(u--) to while(u-- != 0).

... or while(u-- >0) just in case u starts off negative. (OK, b.size() will never be negative -- but consider a general case where perhaps something else initialised u).

Or, to make it even clearer:

u = b.size();
v = b.back();
while(u>0) {
   u--;
   b[u] = v;
   v = p[v];
}

It's better to be clear than to be terse.

Solution 3:

The condition is u--;, because it is in the second position of the for instruction.

If the value of u--; is different from 0, it will be interpreted as true (i.e., implicitly casted to the boolean value true). If, instead, its value is 0, it will be casted to false.

This is very bad code.

Update: I discussed the writing of "for" loops in this blog post. Its recommendations can be summarized in the following paragraphs:

A for loop is a practical, readable (once you get used to it) and terse construct, but you need to use it well. Because of its uncommon syntax, using it in a too imaginative way is not a good idea.

All parts of the for loop should be short and readable. Variable names should be chosen to make it easy to understand.

This example clearly violates these recomendations.