The argument to any of the character handling functions (to*() and 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 char and 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
getchar(),getc(), andfgetc()always return a value in the range ofunsigned char(or the special valueEOF), so their return values may be passed directly to the character handling functions. A cast is undesirable in this situation because it would mapEOFto some character (oftenUCHAR_MAX).(There is a theoretical exception: an implementation that has
sizeof(int) == 1will haveUCHAR_MAX > INT_MAX, so that any character with value greater thanINT_MAXwill be an invalid argument to character handling functions, unless the character happens to equalEOF. 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 thechar, 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 ofunsigned 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.