2016-11-22 27 views
4

引入了wchar_t的ISO C90标准并没有说明关于该表示的任何具体内容。它只需要 这种类型能够存储基本字符集的所有元素。为什么参数类型的`putwchar()`,`fputwc()`和`putwc()`不是`wint_t`?

这意味着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 

S型 转换警告o唯一的选择是使它成为int,它可以保存签名和未签名的char

尽管通过putchar()函数自变量转换为unsigned char,即使它是作为int或signed char传递的,但在putwchar()函数中不会执行任何操作。

那么,为什么fputwc()putwc()putwchar()采取wchar_t,不wint_t?看起来像标准中的缺陷。我错过了明显的东西吗?

参见​​和Why argument type of putchar(), fputc() and putc() is not char?Inconsistency in definitions of fputwc(), putwc() and putwchar() in glibc


UPDATE

如果wchar_t被定义为char从glibc的参考一些报价wint_t必须定义为类型由于参数提升。

这将是合法的定义wchar_tchar

是事实,这些功能已经在 “ISO工作文件SC22/WG14/N204月31日1992年3月” 正确的接口(其中是发布“ISO/IEC 9899:1990 /修订版1:1995”之前的最终草案),但在“ISO/IEC 9899:1990 /修订版1:1995”中进行了修改。看到这里http://www.unix.org/version2/whatsnew/login_mse.html

回答

2

这是一个有趣的问题,但不幸的是我认为答案是由于历史原因。这个答案的其余部分只是我的看法,我没有提及它。

fputc家庭由于K & R C,第一版本,其中的功能原型根本不存在存在:你应该知道什么参数类型接受一个函数,没有可能发生在函数调用隐式转换。由于fgetc家人返回一个int,它决定对称fputc人会采取一个int参数,让下面的结构:

fputc(fgetc(fd1), fd2); 

如果fputc采取了字符,它应该被写(K & RC):fputc((char) fgetc(fd1), fd2);

但是现在,只有恐龙才能记得K & R,并且在函数调用中会发生隐式转换。因此,当宽字符集功能被添加到标准库时,决定只通过用于避免双重转换的部分,因为仅使用wchar_t,因此避免了双重转换wchar_t - >wint_t - >wchar_t。而且它是在fputs定义明确的(强调矿):

int fputc(int c, FILE *stream);
描述:的fputc功能通过流写入由C(转换为unsigned 炭)到输出流中指定的字符指向...

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

+0

'fputc'的定义是正确的,它不需要改变 - 阅读OP的基本原理,这里http://stackoverflow.com/a/40732303/1487773/和'fputwc'是不正确的 - 出于同样的原因因为wchar_t与char没有区别 - 请参阅OP) –

+0

宽字符的所有功能都必须类似于普通字符的功能,不包括自动提升发挥作用的情况。 –

相关问题