为什么`putwchar()`,`fputwc()`和`putwc()`的参数类型不是`wint_t`?

引入wchar_t的ISO C90标准没有说明

关于表示的任何具体内容.它只需要

此类型能够存储基本字符集的所有元素.

这意味着wchar_t可能是char类型,wint_t可能是
int类型此外,在一些实现中,可以签署wchar_t,
在某些 – 未签名.情况与putchar()有何不同?

为了比较,putchar(),putc()和fputc()的参数
被选为int.

我认为没有处理单一的库函数
字符使用char(仅使用int),因为即使
其中一些不使用EOF(如putchar()),我们无法使其类型为char,
因为如果它是char,并且我们对unsigned char进行类型转换(char的签名未标准化),则会有类型
像转换警告一样

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

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

所以唯一的选择是使它成为int,它可以包含signed和unsigned char.

虽然参数由putchar()自动转换为unsigned char,即使
它作为int或signed char传递,没有任何类型的东西在putwchar()中完成.

那么,为什么fputwc(),putwc()和putwchar()需要wchar_t,而不是wint_t?似乎是标准中的缺陷.我错过了一些明显的东西吗

另见Why islower() and friends are required to handle EOF?Why argument type of putchar(), fputc() and putc() is not char?Inconsistency in definitions of fputwc(), putwc() and putwchar() in glibc

UPDATE

glibc引用的一些引用

if wchar_t is defined as char the type wint_t must be defined as int due to the parameter promotion.

it would be legitimate to define wchar_t as char

事实上,这些功能在1992年3月31日的“ISO工作文件SC22 / WG14 / N204”中具有正确的界面(这是在发布“ISO / IEC 9899:1990 / Amendment 1:1995”之前的最终草案),但它们已被更改在“ISO / IEC 9899:1990 / Amendment 1:1995”中.见http://www.unix.org/version2/whatsnew/login_mse.html

最佳答案 这是一个有趣的问题,但不幸的是,我认为答案仅仅是出于历史原因.这个答案的其余部分只是我的意见,我没有参考.

自从K& R C的第一个版本开始存在fputc系列,其中函数的原型甚至不存在:您应该知道函数接受了哪些参数类型,并且在函数调用中不会发生隐式转换.当fgetc系列返回一个int时,决定对称的fputc将使用int作为参数来允许以下构造:

fputc(fgetc(fd1), fd2);

如果fputc采用了char,则应该写入(K& R C):fputc((char)fgetc(fd1),fd2);.

但现在,只有恐龙可以记住K& R,并且在函数调用中确实会发生隐式转换.因此,当将宽字符集函数添加到标准库时,决定仅传递用于避免双重转换的部分wchar_t – > wint_t – > wchar_t因为只使用了wchar_t.它在fputs定义中是明确的(强调我的):

int fputc(int c, FILE *stream);
Description: The fputc function writes the character specified by c (converted to an unsigned
char
) to the output stream pointed to by stream…

所以它不是很连贯,但我想没有人真的认为有必要改变旧fputc家族功能的定义……

点赞