Do you use i-->0 for backward loops?

Some people write

``````for (int i=N; i-->0; ) doSomething(i);
``````

``````for (int i=N-1; i>=0; --i) doSomething(i);
``````

for backward loops. The `--> "operator"`1 looks very confusing at the first glance, but it's trivial:
`i-->0` simply parses as `(i--)>0`, and once you get it, you see it immediately.

The main disadvantage is the strange look. The advantage is that you'll get it always right (unlike the more verbose version offering the possibility to forget something, which really happened to me a couple of times).

What do you think about using the `--> "operator"`?

1First time I saw the funny term in a comment to this question today.

-
It's actually a very well-known joke and also the subject of a legendary StackOverflow question (which points back to a comp.lang.c++.moderated post from a couple of years back). –  Deckard Apr 25 '11 at 20:19
To whoever downvoted, I'm curious to know why. This is a perfectly valid question. –  Anto Apr 25 '11 at 20:57
I can never remember what `--i` and `i--` translate into so being explicit about what's being tested and what's being decremented or increment is a much better approach. Your way just adds extra cycles to parsing the code instead of understanding what algorithm is being implemented. –  davidk01 Apr 26 '11 at 9:28
@davidk01: You should just learn it. As the name says, predecrement decrements the variable first and then returns the result, while postdecrement first returns the value and then decrements the variable. This belongs to basics of many languages and should not halt anybody from anything. That said, I agree that cryptical constructions are to be avoided. –  maaartinus Apr 26 '11 at 11:34
I'm afraid he wasn't. As he wrote, he only knows `i = i - 1`. We could start discussing if knowing `=` and `-` is a trivial detail. –  maaartinus Aug 17 '11 at 11:13

My preferred idiom is:

``````for (i = n; i--;)
``````

Shorter and clearer, fewer moving parts, no confusion with arrows.

-
Yes, that's perfect. Maybe, that's why somebody managed to downvote it already. –  maaartinus Aug 17 '11 at 6:08
Note that if you haphazardly alter i inside the loop you risk an infinite loop. –  user1249 Aug 17 '11 at 8:11
@Thorbjørn Ravn Andersen: This is always the case, no matter how you verbosely write the loop. –  maaartinus Aug 17 '11 at 10:49
Its also less explicit. Remember while it might be more clear to you someone else might have an issue. I feel that "for (i = n; i >=0; i--)" would cause less issues for others. Its the same reason why I hate for(;;) as opposed to while( true ) for infinite loops. I guess my point is that you don't get extra points for cleverness. –  barrem23 Dec 7 '11 at 17:21
@barrem23: Your loop is more explicit, but it's wrong (in the sense it does something else than mine). And that's exactly the problem: I can either make it nice or error-proof, not both. –  maaartinus Nov 13 '12 at 14:51

Nope. It reminds me too much of an arrow, which in some other languages has a different meaning. Simply, no.

I find i=n-1 very easy to read (cannot be misunderstood!), and do not feel the need to change it just so it looks uniform with the other one.

-
-1. If `i` is unsigned (which it should be if `n` is unsigned), `for (i = n-1; i >= 0; i--)` will be an infinite loop. –  Joey Adams Aug 30 '11 at 13:00
@Joey - Then don't write it so it goes in an infinite loop! :/ –  Rook Aug 30 '11 at 13:07
How? `for (i = n-1; i+1 > 0; i--)` ? –  Joey Adams Aug 30 '11 at 13:09
@Joey - Any other way you can, or at all. –  Rook Aug 30 '11 at 13:15

No. I do not. This is because it was completely unclear to me before reading the explanation, and I believe others will think the same.

Sure, it looks pretty and what not, but no, it is very unclear to others.

-

The syntax `-->` is not an operator; there are two different operators here that have been run together through clever (read bad) formatting; these are `--` (applied as a postfix decrement to `i`) and `>`.

It's clever, but not as clever as the fast inverse square root and it's easier to understand, but that doesn't mean that you should use it. It is uncommon and other programmers would have to sit and think about it for a minute or two to make sure your code actually worked. Personally I think it should be avoided.

-
In your first paragraph your restate what I wrote in the question itself. --- I surely agree that the very first time it takes some time to understand the expression, but what's two minute once in a life? Don't get me wrong, I'm not promoting the use of `-->`. –  maaartinus Apr 25 '11 at 21:06
In the first paragraph I state that it is not an operator, you say it is; at most it is a pattern. Programmers are a conservative bunch; you try getting that through a code review. –  user23157 Apr 25 '11 at 21:13
@B Tyler: Writing `operator` and `"operator"` means something different; the quotes should make clear it's not serious. I also explained that it parses as `(i--)>0`, which IMHO must make it clear. –  maaartinus Apr 25 '11 at 21:39
@maaartinus: OK, so you have idiosyncrasies that will take me two minutes to realize and parse each. Now, suppose I have to figure out what's wrong with something you wrote. I know something's wrong, so I'm being alert to things that look wrong. If I have to spend minutes figuring out what a line of your code does, and then remember that it just looks odd, I'm not going to be happy with you. –  David Thornley Apr 25 '11 at 21:47
@maaartinus: The big problem is that it's surprising. If K&R had used it consistently, it would be as understood as `while (*dst++ = *src++);`. –  David Thornley Apr 25 '11 at 22:06

The purpose of using idioms is that when another programmer sees that line in your code will understand it right away and doesn't have to think much about it. While the --> version is syntactically correct, it's bad code. Bad, because it's not how most people program, and most code is read more than written. The second one is an idiom. Use that (and you avoid people cursing your name).

-

There's a very good reason to beware of this:

``````for (i=N-1; i>=0; --i)
``````

If `i` happens to be unsigned, this code will have a subtle bug. Namely, when `N` is zero, `i` will start out at 0 minus 1.

When I do down-counting loops, I usually put a space between the `--` and `>`:

``````for (i = N; i-- > 0;)
``````

This is a perfectly legitimate pattern. Sure, it's short and cute and "cryptic", but it also happens to be correct.

-
No, for unsigned int, the condition `i>=0` is always true, so the first loop never terminates while the second still works. –  maaartinus Apr 26 '11 at 11:31
Of course, if `i` is unsigned and `N` is negative, the second one is going to be a very long loop. –  David Thornley Apr 26 '11 at 13:45
I accept this answer because it's the only one mentioning the problem with unsigned and because of the other answers being all about the same. –  maaartinus Apr 26 '11 at 21:47
You mention that your second proposal is "correct," but it looks to me like it still doesn't handle the case where `i` is unsigned and `N` is zero. –  seh Aug 17 '11 at 4:23
@seh: Why not? You start with `i=0`, test `i>0` and abort the loop. –  maaartinus Aug 17 '11 at 6:06

As I wrote in my answer on the StackOverflow thread on this topic:

It is to prevent confusion (obfuscation, perceived cleverness etc) such as this, that static analysis checkers (eg) MISRA seeks to prevent assignment operations (including `++` and `--` as well as the obvious `=`) in conditional statements.

As (alledgedly) Professional Programmers, we should be writing code that is clear, concise, easy to understand and maintainable.

Not a bunch of clever-dicks who think smart-arsed tricks are neat.

And relying on side effects (no matter how well defined they may be) doesn't aid clarity.

-

I think it's sweet, but will confuse someone.

Reminds me of a loop I formerly used for a MCU:

``````int8_t cycles = ...
while(cycles-->0)  {...}
``````

Of course, if you need a zero based index you have to use `--cycles` which would break the arrow. Sometimes, I would prefer shorter `while` loops in place of the `for` ones, and I do like rwallace's solution.

-
Actually, you do get a zero-based index when you use the arrow. The one-based index is compared against 0. Within the loop body, though, you are using the already-decremented value. –  Joey Adams Aug 17 '11 at 17:59
Oh, ähm... of course, you're right! –  jfk Aug 20 '11 at 17:11