HN
Today

Iterating Backwards in C

Struggling with C's size_t in reverse loops? This post reveals the concise and correct for(size_t i = count; i--; ) idiom. It's a fundamental C best practice that elegantly sidesteps common unsigned integer pitfalls and current LLM-induced errors, making it a must-know for anyone wielding a C compiler.

11
Score
5
Comments
#8
Highest Rank
8h
on Front Page
First Seen
Oct 30, 1:00 AM
Last Seen
Oct 30, 8:00 AM
Rank Over Time
178121211231529

The Lowdown

The article tackles a common C programming challenge: iterating a buffer backwards without running into common pitfalls with unsigned integers. While forward iteration is typically straightforward, reversing the loop often leads to incorrect or overly complex code.

The author highlights the problems with common reverse iteration attempts:

  • A naive for(size_t i = count - 1; i >= 0; i--) fails because i >= 0 is always true for size_t, leading to infinite loops or SIZE_MAX wrap-around if count is zero.
  • Switching to ssize_t (signed size_t) remedies the loop condition but introduces its own set of issues: potential signed/unsigned conversion woes, platform dependency (POSIX), and increased complexity in expressions.

The recommended, correct, and elegant solution is presented as for(size_t i = count; i--; ).

This method leverages the post-decrement operator: i-- evaluates i before decrementing it. The loop continues as long as the pre-decrement value of i is non-zero. This means the loop naturally processes indices from count-1 down to 0. When i is 1, i-- evaluates to 1 (true), the loop executes for index 0 (since i becomes 0 after the check), and then i is 0. When i is 0, i-- evaluates to 0 (false), and the loop terminates. This approach avoids signed types entirely, relies on well-defined unsigned wrap-around for termination, and is much cleaner.

In conclusion, the article promotes for(size_t i = count; i--; ) as the superior and more readable pattern for backward iteration in C, encouraging developers to adopt it and correct others who use less robust methods.

The Gossip

Arrow-verse Iteration: The `-->` Operator

Many commenters couldn't resist showcasing the visually distinct `while (i --> 0)` or `for (size_t i = n; i --> 0;)` syntax. This 'goes to' operator, formed by `i-- > 0`, is acknowledged as 'too clever' or a 'certain kind of taste' but often admired for its correctness and quirky readability once understood. Discussions touched upon its applicability (or lack thereof) with `ssize_t` and drew parallels to explicit `downto` constructs found in languages like VHDL.

Seasoned Solutions: Veteran Validation

A strong sentiment in the comments was validation from long-time C programmers. Many confirmed they have been using the `for(size_t i = count; i--; )` pattern for decades, reinforcing its status as a time-tested and correct idiom. This widespread familiarity suggests the article is less about a novel trick and more about re-emphasizing a robust, elegant solution to a common C problem.