Let's say I want to iterate over all integers in a for
loop. For the sake of discussion, assume I am calling some unknown function f(unsigned x)
for each integer:
for (unsigned i = 0; i < UINT_MAX; i++) {
f(i);
}
Of course, the above fails to iterate over all integers, because it misses one: UINT_MAX. Changing the condition to i <= UINT_MAX
just results in an infinite loop, because that's a tautology.
You can do it with a do-while
loop, but you lose all the niceties of the for
syntax.
Can I have my cake (for
loops) and eat it too (iterate over all integers)?
You'll have to perform the test at the end of the loop body, much like a do-while:
for (unsigned int i = 0; /* nothing */; i++) {
...
if (i == UINT_MAX) {
break;
}
}
For a test in the standard for loop test position to work, you would need to track the current iteration in a way that can distinguish between UINT_MAX+2 states: one for each time you enter the loop body, and one for the one time you don't. A single unsigned int can't handle that, so you'd need at least one auxiliary variable or a bigger loop counter.
You can do it with a do-while loop, but you lose all the niceties of the for syntax.
It is still doable with do-while loop by using an anonymous block scope:
{
unsigned i = 0;
do { f(i); } while (++i != 0);
}
While this construct may not be most idiomatic, it is an obvious candidate for clear assembly code. For example, gcc -O
compiles it as:
.L2:
mov edi, ebx ; ebx starts with zero
call f
add rbx, 1
cmp rbx, rbp ; rbp is set with 4294967296
jne .L2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With