Reputation: 19
#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
Reputation: 223389
The program prints “255” because the loop iterates through 255 values before c
becomes zero again, triggering the condition to end the loop.
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.
++c
is a surprising complicated operation:
c += 1
.c += 1
to be equivalent to c = c + 1
, except that the lvalue for c
is evaluated only once.+
.int
arithmetic being used. Since int
represents values up to at least 32,767, no out-of-range issues occur in this addition.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
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
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.
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.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
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