Why argument type of `putchar()`, `fputc()` and `putc()` is not `char`?

做~自己de王妃 提交于 2019-11-28 05:04:16

问题


Does anybody know Why argument type of putchar(), fputc() and putc() is not char, but argument type of putwchar(), fputwc() and putwc() is wchar_t? See also this and this.


回答1:


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 int (short was promoted to int too, and float to 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 character type even if you pass a value that's out of range. The specification of fputc(int c, FILE *stream) says:

The fputc function writes the character specified by c (converted to an unsigned char) to the output stream pointed to by stream

Default promotion rules

§6.5.2.2 Function calls

¶6 If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions.

¶7 … The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.

Integer promotions are defined in §6.3.1

¶2 The following may be used in an expression wherever an int or unsigned int may be used:

  • An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int.
  • A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions.

¶3 The integer promotions preserve value including sign. As discussed earlier, whether a 'plain' char is treated as signed is implementation-defined.

58) The integer promotions are applied only: as part of the usual arithmetic conversions, to certain argument expressions, to the operands of the unary +, -, and ~ operators, and to both operands of the shift operators, as specified by their respective subclauses.

The integer ranks are defined in ¶1 of the section in 10 bullet points.




回答2:


I think that Jonathan's answer is too simple. Things are slightly more rational. I think that none of the library functions which handle single characters work with char (only with int), because even though some of them do not use EOF, we cannot make its type char without getting type conversion warnings like

void f(char c) { ...
...
char x = 't';
f((unsigned char)x);
...

warning: conversion to ‘char’ from ‘unsigned char’ may change the sign of the result

(because people usually typecast to unsigned char to ensure portability of the code, considering the fact that the signedness of char is undefined.) So the only option was to make it int.



来源:https://stackoverflow.com/questions/40712493/why-argument-type-of-putchar-fputc-and-putc-is-not-char

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!