For (unsigned char i = 0; i <= 0xff; i ++) creates an infinite loop

Why does the following c code end up in an infinite loop?

for(unsigned char i = 0; i <= 0xff; i++){}

      

This is the same result:

for(unsigned char i = 0; i <= 0xff; ++i){}

      

How do I change the code so that it works as expected (without using int

or unsigned int

)?

+3


source share


4 answers


A typical loop for

relies on the ability to detect an end condition after the last iteration of the loop. In your case, as other answers i <= 0xff

have pointed out, is always true (given what i

is of type unsigned char

and what UCHAR_MAX==0xff

, what is typical).

You might run into the same problem near the bounds of any integer type. For example, this:

for (int i = INT_MAX - 9; i <= INT_MAX; i ++) {
    /* ... */
}

      

(possibly) also an infinite loop (except that overflow for signed integers has undefined behavior as opposed to well-defined semantics for unsigned integers, and an optimization compiler can take advantage of that and - but I'm digressing). Just don't do it.

One of the many solutions is to move the test to the bottom of the loop before incrementing:



for (unsigned char i = 0; ; i ++) {
    printf("%d\n", i);
    if (i == 0xff) break;
}

      

The second clause of the loop for

is a termination condition that is evaluated before each iteration. If you leave it blank, it will always be considered true, which will give you an infinite loop (which for (;;)

is a common idiom for a simple infinite loop). We check to see if is i

equal to 0xff

at the bottom of the loop. If so, we have just performed the last iteration and we can exit the loop.

(Some may prefer to use a loop here while

, but I like for

it because it allows you to combine the declaration of a loop control variable and gain in a single construct.)

(Strictly speaking, the maximum value is unsigned char

not necessary 0xff

or 255

, but it will be in whatever system you are likely to run into. Implementations for some DSPs have CHAR_BIT > 8

, and therefore will UCHAR_MAX > 255

.)

+4


source


If you really need to use unsigned char

, you can use

unsigned char i = 0;
do {
    // ... 
} while(++i);

      



When an arithmetic operation on an integer unsigned

violates its limits, the behavior is well defined. So this solution will handle 256 values ​​(for 8-bits unsigned char

).

+16


source


The range unsigned char

is 0 to 255 (0xff). Adding 1 to 0xff makes 0x100, which, when returned to, unsigned char

wraps back to 0.

Thus, the comparison i <= 0xff

will always be true. Hence the endless cycle.

If you want the loop to stop after 0xff, use int

as data type. This range is at least -32767 to 32767 and usually more.

+8


source


Because you are deceived. Unsigned char values ​​are in the range 0 to 255, but because unsigned arithmetic juggles well, you actually roll the value i

to 0 and the condition is still met and the iteration continues indefinitely.

In the case of signed values, this behavior is undefined, and the value stored in i may not be 0. But it will still be less than the maximum value you could store in a char, and the condition is still met.

+2


source







All Articles