The argument to any of the character handling functions (
is*()) should generally include a cast to
unsigned char to coerce it into the proper range, as in
toupper ((unsigned char) c). The problem is that most of the time it is a
char that should be passed to these functions, but whereas their arguments are required to be within the range of
unsigned char (or the special value
EOF). Regrettably, the ranges of
unsigned char can be different; in particular,
char can have the same range as
signed char. Adding the cast maps negative
char values into positive
unsigned char values, fixing the problem.
However, under some circumstances, casting to
unsigned char is unnecessary or even harmful:
The character input functions
fgetc()always return a value in the range of
unsigned char(or the special value
EOF), so their return values may be passed directly to the character handling functions. A cast is undesirable in this situation because it would map
EOFto some character (often
(There is a theoretical exception: an implementation that has
sizeof(int) == 1will have
UCHAR_MAX > INT_MAX, so that any character with value greater than
INT_MAXwill be an invalid argument to character handling functions, unless the character happens to equal
EOF. But these implementations are invariably free-standing, meaning that they don't implement the character handling functions anyway.)
Of course, if you store the return value of one of these function in a
charobject, then pass the
char, the cast becomes necessary again.
The characters in the basic character set, which includes capital and lowercase English letters, digits, and some punctuation, always have positive values as
char(and thus in the range of
unsigned char), so they need not be cast.
If the argument is already an
unsigned char, of course no cast is necessary.
Many implementations are flexible about arguments to character handling function, reporting correct results whether the argument is in the proper range or not. Others will crash, so it's best to be careful.