Cuando se itera hacia adelante a través de un arreglo en C, el patrón estándar es sencillo: inicializar un índice `size_t` en 0, verificar que sea menor que el conteo e incrementarlo. Sin embargo, intentar replicar esta lógica para una iteración hacia atrás a menudo conduce a errores sutiles. Un error común es inicializar el índice en `count - 1` y verificar si es mayor o igual a 0. Debido a que `size_t` es un tipo sin signo, la condición `i >= 0` siempre es verdadera (tautológica), lo que puede provocar bucles infinitos o accesos a memoria fuera de los límites. Además, si el conteo es 0, la expresión `count - 1` se envuelve al valor máximo posible para ese tipo (`SIZE_MAX`), causando errores inmediatos.
Las soluciones alternativas, como cambiar a un tipo de entero con signo como `ssize_t`, pueden funcionar pero introducen sus propias complejidades. Los enteros con signo pueden causar problemas durante las conversiones de tipo implícitas en expresiones de C, y `ssize_t` no es estándar en todas las plataformas (como Windows). Además, en sistemas de 32 bits, el uso de enteros con signo para búferes grandes puede provocar problemas de promoción o truncamiento. Estos rodeos a menudo resultan en encabezados de bucle excesivamente complicados que requieren una inspección cuidadosa para asegurar que la lógica sea correcta, lo que hace que el código sea más difícil de mantener y más propenso al error humano.
David Priver propone una solución más limpia e idiomática que evita estas trampas utilizando el operador de postdecremento dentro de la inicialización y la condición del bucle. El patrón `for (size_t i = count; i--; )` inicializa `i` con el conteo total. El postdecremento `i--` se evalúa como parte de la condición del bucle; decrementa el valor pero devuelve el valor que tenía *antes* del decremento. Esto asegura que la primera iteración use `count - 1` (el último índice válido), y el bucle termina cuando `i` era 0 antes del decremento. Debido a que el desbordamiento sin signo está bien definido en C, el bucle termina de forma segura cuando `i` se envuelve de 0 a `SIZE_MAX` después de la iteración final. Este enfoque sigue siendo simple, legible y evita la necesidad de conversiones a tipos con signo.
