I read in the Dennis Ritchie's The C Programming Language book that int
must be used for a variable to hold EOF – to make it sufficiently large so that it can hold EOF value – not char
. But following code works fine:
#include<stdio.h>
main() {
char c;
c=getchar();
while(c!=EOF) {
putchar(c);
c=getchar();
}
}
When there is no more input, getchar
returns EOF. And in the above program, the variable c
, with char type, is able to hold it successfully.
Why does this work? As per the explanation in the book above mentioned, the code should not work.
Best Answer
Your code seems to work, because the implicit type conversions accidentally happen to do the right thing.
getchar()
returns anint
with a value that either fits the range ofunsigned char
or isEOF
(which must be negative, usually it is -1). Note thatEOF
itself is not a character, but a signal that there are no more characters available.When storing the result from
getchar()
inc
, there are two possibilities. Either the typechar
can represent the value, in which case that is the value ofc
. Or the typechar
can not represent the value. In that case, it is not defined what will happen. Intel processors just chop off the high bits that don't fit in the new type (effectively reducing the value modulo 256 forchar
), but you should not rely on that.The next step is to compare
c
withEOF
. AsEOF
is anint
,c
will be converted to anint
as well, preserving the value stored inc
. Ifc
could store the value ofEOF
, then the comparison will succeed, but ifc
could not store the value, then the comparison will fail, because there has been an irrecoverable loss of information while convertingEOF
to typechar
.It seems your compiler chose to make the
char
type signed and the value ofEOF
small enough to fit inchar
. Ifchar
were unsigned (or if you had usedunsigned char
), your test would have failed, becauseunsigned char
can't hold the value ofEOF
.Also note that there is a second problem with your code. As
EOF
is not a character itself, but you force it into achar
type, there is very likely a character out there that gets misinterpreted as beingEOF
and for half the possible characters it is undefined if they will be processed correctly.