an9xia
an9xia

Reputation: 19

Why is the output 255 instead of infinity?

#include <stdio.h>

int main(void){
    char c = 0;
    int count=0;
    for (;++c;)
        count++;
    printf("%d", count);
    return 0;
}

Why is this program printing 255 instead of going to infinity?

Upvotes: 1

Views: 365

Answers (4)

Eric Postpischil
Eric Postpischil

Reputation: 223389

Short Answer

The program prints “255” because the loop iterates through 255 values before c becomes zero again, triggering the condition to end the loop.

Medium Answer

C permits char to be signed or unsigned. If it is unsigned, char is eight bits in your C implementation, and the program increments it from 1 to 255. The next increment resets it to zero, because unsigned arithmetic and conversions are defined to wrap, and the loop stops.

If char is signed, the behavior of ++c when the value would be out of range of char is implementation-defined (due to a chain of rules in the definition of ++). Most likely your implementation uses an eight-bit char with values from −128 to 127, and, when the value would go to 128, it is wrapped to −128. Thus, 255 values are counted (127 from 1 to 127 and 128 from −128 to −1) before c becomes zero again and the loop stops because its test expression, ++c, evaluates to zero.

A theoretical possibility under the C standard that does not occur in practice is that your implementation uses a nine-bit char with values from −256 or −255 to 255 and, when the value would go to 256, it is reset to zero.

Long Answer

++c is a surprising complicated operation:

  • C 2018 6.5.3.1 2 defines it to be equivalent to c += 1.
  • C 2018 6.5.16.2 3 defines c += 1 to be equivalent to c = c + 1, except that the lvalue for c is evaluated only once.
  • C 6.5.6 4 tells us that the usual arithmetic conversions are performed on the operands of +.
  • The usual arithmetic conversions involve several clauses in 6.3 that result in int arithmetic being used. Since int represents values up to at least 32,767, no out-of-range issues occur in this addition.
  • Finally, C 6.5.16.1 2 tells us the result of the addition is converted to char. This is where the interesting things happen with out-of-range values.

C 2018 6.3.1.3 tells us what happens with conversions to char. There are only three ways that the loop could iterate through 255 values and then produce zero in c:

  • char is unsigned and eight bits, so it represents values from 0 to 255. When the addition produces 256, 6.3.1.3 2 tells us the conversion wraps modulo 256, producing zero.
  • char is unsigned, eight bits, and two’s complement, so it represents values from −128 to +127. When the addition produces 128, 6.3.1.3 3 tells us the result is implementation-defined. Your implementation produces −128. After that, the increments proceed from −128 to −1 and to zero, and then the loop stops.
  • char is unsigned, and no bits, so it represents values from either −256 or −255 to +255. When the addition produces 256, your implementation produces zero. Then the loop stops. (This does not occur in normal practice; it is only a theoretical possibility under the C standard.)

We know char is either eight or nine bits because that is the only way the count could be 255. If it were seven bits (which the C standard does not permit anyway), there is no way to count 255 distinct values. If it were ten bits or more, the count would go up to at least 511 before the implementation-defined conversion could reset c.

Upvotes: 0

axiac
axiac

Reputation: 72256

The data in computers is stored on a certain amount of memory. In this case, c (of type char) is stored on one byte, consequently it may have only 256 distinct values. If you insist on incrementing its value it wraps and when it reaches 0 again the for loop completes.

Given that it starts with 0 and it is incremented before checking its value, the for loop runs only 255 times; on the 256th increment of c its value becomes 0 again.

Upvotes: 0

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

First of all, no integer is ever going to reach infinity. Integers have a fixed range of values. You could probably have expected your int count to get to a value like 2,147,483,647 (32-bit) or 9,223,372,036,854,775,807 (64-bit).

The reason it didn't, is that that's not what your program does. Your program increments count only while ++c as a boolean condition evaluates truthfully. That stops happening once c itself runs out of values.

  • If char is signed in your environment, that happens at 127; then, having reached the maximum possible value for such a type, you run into complicated and implementation-defined rules, in your case apparently wrapping around back to -128 then proceeding to 0. That's 255 steps.
  • If it's unsigned, it goes from 0 to 255 then wraps back to 0 in a well-defined manner. That's still 255 steps.

The following subtly altered for loop moves the increment of c from the condition part into the post-iteration step part, so it no longer determines how long the loop runs for:

for (;;++c)
 count++;

However, now your whole program has undefined behaviour because it describes a thread that never terminates or performs I/O.

Upvotes: 3

Hatted Rooster
Hatted Rooster

Reputation: 36503

Because your char type can only hold 0 - 255 (or -128 - 127, that doesn't matter in this case). After 255 it will overflow and go back to 0. 0 evaluates to false and thus the for loop is broken.

Upvotes: 1

Related Questions