4

引入 wchar_t 的 ISO C90 标准没有说明有关表示的任何具体内容。它只要求这种类型能够存储基本字符集的所有元素。

这意味着 thatwchar_t很可能是 type char,并且wint_t可能是 type int。此外,在一些实施wchar_t方式中,可能是有符号的,而在一些实施方式中,可能是无符号的。情况有何不同putchar()

为了比较, 和 的putchar()论点putc()fputc() 选为int

我认为处理单个字符的库函数都不能与(char仅与)一起使用,因为int即使其中一些不使用 EOF(如的签名不是标准化的),会有类型转换警告,如putchar()charcharunsigned charchar

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?似乎是标准中的一个缺陷。我错过了一些明显的东西吗?

另请参阅为什么需要 islower() 和朋友来处理 EOF?为什么论点类型是putchar(),fputc()putc()char不是以及glibc 中 fputwc()、putwc() 和 putwchar() 的定义不一致


更新

来自 glibc 参考的一些引文

ifwchar_t被定义为char类型wint_t必须被定义为int由于参数提升。

定义wchar_tchar

事实上,这些功能在“ISO Working Paper SC22/WG14/N204 日期为 1992 年 3 月 31 日”(这是发布“ISO/IEC 9899:1990/Amendment 1:1995”之前的最终草案)中具有正确的接口,但是它们被更改了在“ISO/IEC 9899:1990/修正案 1:1995”中。见这里http://www.unix.org/version2/whatsnew/login_mse.html

4

1 回答 1

2

这是一个有趣的问题,但不幸的是,我认为答案只是出于历史原因。这个答案的其余部分只是我的意见,我没有任何参考资料。

fputc系列自 K&R C 的第一个版本开始就存在,其中甚至不存在函数原型:您应该知道函数接受哪些参数类型,并且函数调用中不会发生隐式转换。由于该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使用了 a 。它的fputs定义很明确(强调我的):

int fputc(int c, FILE *stream);
说明: fputc 函数将 c 指定的字符(转换为 unsigned char)写入流指向的输出流...

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

于 2016-11-22T10:26:28.880 回答