Comment by dataflow

4 hours ago

> for (size_t i = size - 1; i < size; i--)

Erm... just because you can, doesn't mean you should.

Also, what if you want to go down to something other than 0?

> for (size_t i = size - 1; i < size; i--)

Agreed, seeing that example briefly made me consider whether this blog post was a parody. Sure, it works for this exact example, by relying on i wrapping "down" to MAX_INT on the last iteration. But how long will it take the next developer who works on the code base to figure that out? Will they figure it out before or after committing changes that break it? Or worse yet, before or after shipping code?

That loop reads like a bug to anyone who hasn't memorized the wrapping rules. while (i-- > 0) on a signed index does the same thing.

I really don't see what's supposedly awful about that loop, but if you want to count down to x instead of 0 you just do:

    for (size_t i = size - 1; i >= x; i--)

  • > I really don't see what's supposedly awful about that loop

    The stopping condition is incredibly confusing and non-obvious. Misleading at first glance, in fact. The whole thing is so unidiomatic that I don't think I've even seen it once in my life. It's a better contender for an underhanded C++ code contest than production code.

    > but if you want to count down to x instead of 0 you just do i >= x

    No you can't. That fails if x == 0. Which perfectly illustrates why using unsigned everywhere isn't so great. And I say this as someone who likes unsigned types and uses them more than average!

    • Thinking of it as a "stopping condition" is backwards, that part of the loop is called the invariant:

      https://en.wikipedia.org/wiki/Loop_invariant

      You should think of it as the condition that's true for all iterations, not a one-time event that halts the loop. The loop is short for this:

        for(size_t i = size - 1; 0 <= i && i < size; i--){
        
        }
      

      Which works for both signed and unsigned numbers. It just so happens that for unsigned numbers you can omit the left-hand side of the &&, and for signed numbers you can omit the right-hand side. To support arbitrary lower bounds, you omit neither.