Bo said:
But if char, unsigned char, and int are all the same size (like 32
bits)
Note that char and unsigned char are always the same size. For any integer
type X, signed X and unsigned X are the same size, and for the type char,
plain char is a distinct type otherwise implemented the same as signed char
or unsigned char.
not all values will be used for characters so there is room for
reserving one value for EOF.
There's no basis for saying that.
At any rate, it's irrelevant for fgetc and <ctype.h>. Did you review their
documentation? Here's a proof of what I've been saying:
1. fgetc reads unsigned chars and returns them as ints.
2. For character types, all bits in the object representation participate in
the value representation.
3. All bit patterns of unsigned char are valid numbers.
4. Thus, if unsigned char and int are the same size, unsigned char will
necessarily use up all the values of int.
5. Therefore, there is no int value left over to represent EOF.
6. One cannot implement fgetc, <ctype.h>, and a handful of other library
functions if char and int are the same size, because the int value EOF
cannot be distinguished from a valid unsigned char represented by int, and
those functions require that distinction.
Ok, that is C++ where wide the character type wchar_t uses the value
wchar_t(-1) as the end-of-file signal WEOF for wide streams.
Actually, WEOF appears in the Standard C header <wchar.h>, and it has the
type wint_t, which is not necessarily wchar_t:
http://www.lysator.liu.se/c/na1.html
<q>
typedef ... wint_t;
An integral type unchanged by integral promotion. It must be capable of
holding every valid wide character, and also the value WEOF (described
below). It can be the same type as wchar_t.
WEOF
is an objectlike macro which evaluates to a constant expression of type
wint_t. It need not be negative nor equal EOF, but it serves the same
purpose: the value, which must not be a valid wide character, is used to
represent an end of file or as an error indication.
</q>
This is explicitly spelled out compared to the situation with unsigned char,
int, EOF, fgetc, and <ctype.h>, for which you have to synthesize the
constraints from more fundamental properties.