C 允许大小请求但结果仅为ssize的系统调用的基本原理?
考虑:C 允许大小请求但结果仅为ssize的系统调用的基本原理?,c,linux,unix,C,Linux,Unix,考虑: ssize_t write(int fd, const void *buf, size_t count); 必须对结果进行签名,以说明错误等情况下的-1,因此是ssize\t。但是,当请求超过ssize_t的结果未定义时,为什么允许请求为未签名的金额(两倍大) 由于不检查count参数的符号性,内核中是否存在显著的优化?或者别的什么?write只能从一个连续的无符号字符数组中写入,该数组不能大于PTRDIFF\u MAX,该数组(在所有真实的POSIX系统上,可能POSIX也需要它…?
ssize_t write(int fd, const void *buf, size_t count);
必须对结果进行签名,以说明错误等情况下的-1,因此是ssize\t。但是,当请求超过ssize_t的结果未定义时,为什么允许请求为未签名的金额(两倍大)
由于不检查count参数的符号性,内核中是否存在显著的优化?或者别的什么?
write
只能从一个连续的无符号字符数组中写入,该数组不能大于PTRDIFF\u MAX
,该数组(在所有真实的POSIX系统上,可能POSIX也需要它…?)等于SIZE\u MAX/2
。因此,传递一个如果解释为有符号值则为负值的值是一个编程错误——传递的大小与缓冲区中的可用空间不一致
理论上,readv
和writev
可以通过在数组中多次重复相同的iov
缓冲区来执行大于SIZE\u MAX/2
的IO操作,但如果我没记错的话,如果总大小大于SSIZE\u MAX
则指定它们失败,方法是使参数无符号,这样就不需要函数检查无意义的否定请求。根据forSSIZE\u t write(int fildes,const void*buf,size\t nbyte)
如果nbyte的值大于{SSIZE_MAX},则结果由实现定义
因此,每个特定的实现可能会以不同的方式处理这种情况。如果一些实现只是设置EFBIG
,我不会感到惊讶
至于基本原理,从语义上来说,size\u t
可能是表示缓冲区大小的最佳类型?它声明这个参数是一个非负的大小,没有其他任何东西。我认为这很好,因为size\u t
是sizeof
操作符返回的值的类型,这允许这样的调用:
char buffer[1 << 20];
ssize_t wrote;
wrote = write(fd, buffer, sizeof buffer);
char buffer[1最好链接到标准的当前版本。size\t也是sizeof(buffer)的结果类型
,可能用于计算参数的值。@R..;@Cubbi:POSIX.1-2008标准可以在上找到。当然不需要强制转换。C语言对所有算术类型都有隐式转换,尽管有时在目标类型有符号时会有实现定义的行为。使用函数需要无符号带符号的参数并返回带符号的返回值可确保调用方不必担心实现定义的行为(因为无论采用哪种方式,任何转换(如果发生)都将从带符号转换为无符号,因此定义良好)。@R..:write
的实现定义行为与转换的实现定义行为相比,调用方不必担心。@R..:可能存在隐式转换,但不太可能在编译器/lint等中触发警告吗?