考虑:
ssize_t write(int fd, const void *buf, size_t count);
结果必须签名以说明错误等时的-1,因此ssize_t。 但是,当请求超过ssize_t的结果未定义时,为什么要允许请求是未签名的金额(两倍大(呢?
由于不检查 count 参数的符号性,内核中是否有重大优化? 还是别的什么?
根据ssize_t write(int fildes, const void *buf, size_t nbyte)
的文档
如果 nbyte 的值大于 {SSIZE_MAX},则结果是实现定义的。
因此,每个特定的实现可能会以不同的方式处理这种情况。如果某些实现只是设置EFBIG
,我不会感到惊讶。
至于基本原理,也许size_t
只是在语义上表示缓冲区大小的最佳类型?它指出这个参数是一个非负大小,没有别的。
我认为这很好,因为size_t
是sizeof
运算符返回的值的类型,这允许这样的调用:
char buffer[1 << 20];
ssize_t wrote;
wrote = write(fd, buffer, sizeof buffer);
如果函数采用已签名版本,则需要强制转换。此外,正如其他人指出的那样,像这样的语义函数不能接受负值,因此接受它们没有多大意义。
通过使参数无符号,它消除了函数检查无意义的负面请求的需要。
write
只能从单个连续的unsigned char
数组写入,该数组不能大于PTRDIFF_MAX
,这是(在所有现实世界的POSIX系统上,也许POSIX也需要...?(等于SIZE_MAX/2
。因此,传递一个如果解释为有符号值将为负值的值首先是一个编程错误 - 传递的大小与缓冲区中的可用空间不一致。
理论上,readv
和 writev
可以通过在数组中多次重复相同的iov
缓冲区来执行大于 SIZE_MAX/2
的 IO 操作,但如果我没记错的话,如果总大小大于 SSIZE_MAX
,它们被指定为失败。