for (unsigned u = 10; u >= 0; --u)
std::cout << u << std::endl;
I know that unsigned cannot be less than 0
I expected it prints from 10 through 0 because u >= 0
for (unsigned u = 10; u >= 0; --u)
std::cout << u << std::endl;
I know that unsigned cannot be less than 0
I expected it prints from 10 through 0 because u >= 0
// WRONG: u can never be less than 0; the condition will always succeed
for (unsigned u = 10; u >= 0; --u)
std::cout << u << std::endl;
Consider what happens when u
is 0
. On that iteration, we’ll print 0
and then execute the expression in the for loop. That expression, --u
, subtracts 1
from u
. That result, -1, won’t fit in an unsigned value. As with any other out-of-range value, -1
will be transformed to an unsigned value. Assuming 32
-bit ints, the result of --u
, when u
is 0
, is 4294967295
.
One way to write this loop is to use a while instead of a for. Using a while lets us decrement before (rather than after) printing our value:
unsigned u = 11; // start the loop one past the first element we want to print
while (u > 0) {
--u; // decrement first, so that the last iteration will print 0
std::cout << u << std::endl;
}
This loop starts by decrementing the value of the loop control variable. On the last iteration, u
will be 1 on entry to the loop. We’ll decrement that value, meaning that we’ll print 0
on this iteration. When we next test u in the while condition, its value will be 0
and the loop will exit. Because we start by decrementing u
, we have to initialize u to a value one greater than the first value we want to print. Hence, we initialize u to 11
, so that the first value printed is 10
.
You decrement u
each iteration. u
ends up being 0
, u >= 0
still holds true
so another iteration decerements u
again. The unsigned integer wraps around (because unsigned integers can't be negative) and you get u == numeric_limits<unsigned>::max
, rinse and repeat.
If you think of this from another perspective this becomes clear.
The condition for the for loop is u >= 0
. The for loop will stop looping when this is false.
u
cannot be less than 0, as you know. When you decrement it when it is 0 it will wrap back up again, so u >= 0
is always true.
So u >= 0
is never false.
So the for loop is infinite.
If you want to print 10 to 0, you can just use another data type.
In the code block
for (unsigned u = 10; u >= 0; --u)
std::cout << u << std::endl;
u
is unsigned integer and try to find its range which is 0 to 4294967295
. and u>=0
always true So condition never fails which causes loop to run finitely.
u = 10 , 10 >=0 => true => prints 10
..
when u = 0 , 0>=0 => true => prints 0
u = 4294967295 , 4294967295 >=0 true ( it will not -1 > 0 as there is no -1 in the range of unsigned int )
Meanwhile if you rotate loop 10 times, keep the condition like u>0
as
for (unsigned u = 10; u > 0; --u)
std::cout << u << std::endl;