C 为什么FGET接受int而不是size\t?

C 为什么FGET接受int而不是size\t?,c,language-lawyer,size-t,C,Language Lawyer,Size T,函数,如strcpy(),malloc(),strlen()和各种其他函数,由于明显的原因,它们接受参数或返回值作为size\u t而不是int或无符号int 一些文件函数,如fread()和fwrite()也使用size\t。通过扩展,可以预期char*fgets(char*str,int num,FILE*stream)应该使用size\u t而不是int作为其缓冲区大小的参数 但是,使用int。有什么客观的解释吗?原始K&R在第155页上定义了fgets(),带有int参数。这本书中的代码

函数,如
strcpy()
malloc()
strlen()
和各种其他函数,由于明显的原因,它们接受参数或返回值作为
size\u t
而不是
int
无符号int

一些文件函数,如
fread()
fwrite()
也使用
size\t
。通过扩展,可以预期
char*fgets(char*str,int num,FILE*stream)
应该使用
size\u t
而不是
int
作为其缓冲区大小的参数


但是,使用
int
。有什么客观的解释吗?

原始K&R在第155页上定义了
fgets()
,带有
int
参数。这本书中的代码本来是可行的 同时使用
无符号int
(它使用
>0
,但循环的写入方式永远不会低于零)

size\u t
后来在(ANSI C)中作为
sizeof()的类型引入。由于此功能是专门为协调内存分配而引入的,因此
相应地更新了管理函数和字符串函数。但文件I/O并非如此:C89中唯一使用
size\t
的文件函数是那些新函数 由C89引入,在K&R中不存在,例如
fread()
/
fwrite()
。是的,K&R没有这些功能 并且只依赖于使用文件描述符的(不可移植的)unix读/写函数来执行bloc操作

应注意的是,协调了unix功能的是与并行开发的 ANSI C标准和。该标准协调了许多unix函数以使用
size\u t
,因此现在
read()
/
write()
使用
size\u t
定义。但是对于C标准库函数,如
fgets()
,POSIX优先于C标准 (本标准当前版本的措辞):

本参考页上描述的功能与ISO C标准一致。 此处描述的要求与ISO C标准之间的任何冲突都是无意的

具有讽刺意味的是,在POSIX中,
fgets()
仍然继承了其历史上的K&R
int


编辑:附加阅读

  • -多布博士-1989年:
stdio.h:此标题定义并原型化了K&R第7章中列出的大多数函数。在 在K&R中找到定义,但添加了几个新函数


C标准库中没有一致性。功能随着时间的推移而演变<当引入
fgets
时,code>size\u t
可能不存在(我猜是这样)。看到这样的问题总是头晕目眩。我同意@P.P.:这是OT@user2064000如果没有任何真正的理由和引用——就像这里的情况一样——那么人们只会根据自己的想象疯狂猜测,这对我们毫无帮助。这并不一定意味着你会被牵连到要求那样做,但这是现实问题可能产生的结果。这不是以意见为导向的:K&R在第155页定义了
fgets()
,带有
int
参数。他们的代码也可以使用
无符号int
size\u t
后来在C89(ANSI C)中作为
sizeof()的类型引入。因此,内存管理功能得到了更新。但文件I/O并非如此:唯一使用
size\t
的文件函数是C89引入的,在K&R中不存在(例如:fread()/fwrite():K&R在bloc操作中仅使用unix读/写文件描述符,当时没有使用fread/fwrite)您是否知道,当传递负值时,fgets的任何显著的C89之前的实现行为是否可预测[例如,可预测地将其视为零,可预测地不做任何事情,读取-N字节的数据,但省略换行符,等等]?如果是这样,更改为size_t可能会禁止实现支持该功能,除非长度限制为size_t_MAX-UINT_MAX[据我所知,如果在缓冲区结束之前成功读取换行符,则传递大于缓冲区大小的长度是定义的行为]。K&R的实现日期为1978年。由于它是有符号整数,并且第一个循环条件是
--n>0
,它将停止并将空终止符放入缓冲区。完全可以预测。如果参数是无符号的,则同一代码可能会产生缓冲区溢出,但会在最大UINT_MAX迭代后停止(除非硬件捕获符号位的翻转)。然后可能还有其他的实现:89年以前有很多编译器生成器,其中大部分现在已经不为人所知;-)@supercat我可以找到1986年我以前的Lattice C编译器()及其标准库的源代码
fgets()
是通过
for(i=0;ii)实现的,如果值大于缓冲区的大小,但在缓冲区溢出之前接收到换行符,行为会被定义为读取数据直到换行符吗?如果是,这意味着如果
大小
更改为
大小
,那么
fgets(buff,-1,文件)
将定义不同于先前存在的行为。标准的作者不反对将在不同实现中以不同方式定义的行为标记为未定义的行为,因为他们认为这不会阻止任何人继续支持……已定义的有用行为已经在使用[这种期望贯穿二十世纪,但后来受到攻击],但不愿定义任何实现可能以相反方式定义的行为。