引入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
,它可以包含已签名和未签名的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
更新
来自glibc参考的一些引用
如果
wchar_t
被定义为char
,则由于参数提升,必须将wint_t
类型定义为int
。
将
是合理的wchar_t
定义为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
答案 0 :(得分:2)
这是一个有趣的问题,但不幸的是,我认为答案仅仅是出于历史原因的 。这个答案的其余部分只是我的观点,我没有参考。
自K& RC的第一个版本以来fputc
系列已存在,其中函数的原型甚至不存在:您应该知道函数接受的参数类型,并且没有隐式转换可以发生在函数调用中。当fgetc
系列返回一个int时,决定对称fputc
一个将int作为参数以允许以下构造:
fputc(fgetc(fd1), fd2);
如果fputc
使用了字符,则应该写入(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);
描述:fputc函数写入由c指定的字符(转换为无符号 char )到stream ...
所以它不是很连贯,但我想没有人真的认为有必要改变旧fputc
家庭功能的定义......