A wonderful little device in C or C++ which is very useful. It is like your standard loop for(i=0;i<length;i++), except it does the same thing backwards. With while(i--), the loop's contents are executed i times, starting with i-1 and ending with 0. Sometimes it just doesn't matter which order you loop, or even what the value of i is during the loop. In these cases, you are able to use while(i--) to have a more efficient executable.

Why is it more efficient? Well, it only uses one variable in the loop, i, unlike the for loop, which uses i and length.

With gcc on a Pentium:

  • while(i--):
    1. decrement i
    2. test -1 with i
    3. if the result is "not equal", then execute loop contents
    4. otherwise jump out of the loop
  • for(;i<length;i++):
    1. move length into register EAX
    2. test i with EAX
    3. if the result is "less than", then execute the loop
    4. otherwise jump out of the loop
    At the end of the loop execution:
    1. increase i
With optimization enabled, the while loop actually compresses into 2 instructions, using some weird characteristics of the 80x86 processor, whereas the for loop squeezes down to 3 (also using an extra register). (An interesting note: if i is unused in the loop body, gcc will make the for loop count down as if it was while(i--))

The problems

  • Obscure - the meaning of while(i--) is not as obvious as with your standard for loop, but a programmer can get just as used to it as he first did with for.
  • Risky - if i starts out less than 0, the loop will be going way longer than we had expected... This can be solved in either of two ways:
    1. Initially check if i is less than 0.
    2. Use while(i-->=0) - probably just as efficient, but less elegant looking :-)
So, as you can see, while(i--) is quite nice. I came up with the idea, or maybe I "independently invented" it. People who like while(i--) probably also like Duff's Device.