The answer is 'legacy' (or 'history'). Before the C90 standard, there were no function prototypes and all arguments to all functions were subject to default promotion rules, so a
char was automatically passed as an
short was promoted to
int too, and
double, and similarly for unsigned types). The standard couldn't afford to break existing code, so it kept that type for these functions. It makes very little difference in practice. The value you pass will be treated as a
char even if you pass a value that's out of range.