Question

There are two loops below. The first one works well while the second one is an infinite loop. Why?

for (unsigned int i=0; i<3; ++i)
{
    std::cout << "i= " << i << std::endl; // this gives proper result
}

for (unsigned int i=3; i>=0; --i)
{
    std::cout << "i= " << i << std::endl; // infinite loop
}
Was it helpful?

Solution

An unsigned int can never be less than 0. That's what makes it unsigned. If you turn on some warning flags, your compiler should tell you about your problem: i >= 0 is always true for an unsigned value.

Clang, for example, required no special flags at all to warn:

example.cpp:5:29: warning: comparison of unsigned expression >= 0 is always true
      [-Wtautological-compare]
    for (unsigned int i=3; i>=0; --i)
                           ~^ ~
1 warning generated.

GCC required -Wextra:

example.cpp: In function ‘int main()’:
example.cpp:5: warning: comparison of unsigned expression >= 0 is always true

OTHER TIPS

unsigned int cannot be less than zero (which is what loop's condition is checking). When i in your second loop is decremented from 0, it wraps around to UINT_MAX and the loop goes on.

The other answers (so far) are all correct; since i is unsigned, i >= 0 is always true, and so you have an infinite loop.

But that doesn't tell you how to fix it. If you want to iterate over an unsigned range from, say, 3 down to 0, there doesn't seem to be a straightforward way to do it. Other than changing the type of i or the direction of the range (and there may be reasons you can't do that), you could do this:

for (unsigned int i=3; ; --i)
{
    std::cout << "i= " << i << std::endl;
    if (i == 0) break;
}

It's not as clean as a simple for loop with no break but it does the job.

In addition to Keith Thompson's answer, there is another way to write it that doesn't require a break inside the loop:

for (unsigned int i = 3; i--; ) {
    std::cout << "i= " << i << std::endl;
}

Notice how i-- acts both as the termination condition and as the afterthough, all in one. The use of the postfix decrement operator is important because it guarantees you're actually executing the loop 3 times, starting at 2 on the first iteration and ending at 0, included.

The minimum value for unsigned int i is 0; anything else would be negative and require a sign bit which is specifically what an unsigned int won't have.

So i >= 0 will always evaluate to true.

In your second loop ,the condition to stop the loop is that i must be less than 0. The range of unsigned int is 0 to 65535. so, here unsigned int i can't be less than zero. So, your condition is always true as a result the loop become infinite. Using a signed int can solve the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top