ERANGE和EOVERFLOW之间的语义差异是什么?

fuz*_*fuz 10 c posix errno semantics

errnoERANGE由POSIX记录为

结果太大了.

EOVERFLOW记录为

值太大而无法存储在数据类型中.

这两者之间的语义差异是什么?特别是考虑到ERANGEISO 9899(例如in strtol)使用的语义和描述的语义EOVERFLOW.这两个errno值是否仅因历史原因而不同?

如果可能的话,请用适当的来源备份你的论点.

dhk*_*hke 5

SingleUnix非常详细EOVERFLOW:

值太大而无法存储在数据类型中IPC或文件系统对象的用户ID或组ID太大,无法存储到调用者提供的结构的适当成员中.此错误仅发生在支持比声明的结构成员可支持的更大范围的用户ID或组ID值的实现上.这通常是因为IPC或文件系统对象驻留在具有比本地系统更大的类型uid_t,off_t或gid_t的远程计算机上.

EOVERFLOW 似乎是为了表示子系统不兼容,即某些系统返回的值大于另一个子系统可以处理的值.

EOVERFLOW更详细地解释在该理由:

此错误代码的大多数用法与大文件支持有关.通常,这些情况发生在支持具有不同大小的off_t的多个编程环境的系统上,但它们也可能与远程文件系统连接.

另外,当不同的编程环境对于诸如int和uid_t的类型具有不同的宽度时,若干函数可能遇到特定环境中的值太宽而无法表示的条件.在这种情况下,应该提出此错误.例如,假设当前正在运行的进程具有64位int,并且文件描述符9223372036854775807已打开且未设置close-on-exec标志.如果进程然后使用execl()来执行在具有32位int的编程环境中编译的文件,则对execl()的调用可能会失败并且errno设置为[EOVERFLOW].如果要分配给新过程映像的任何用户标识或任何组标识超出执行文件编程环境的范围,则execl()可能会发生类似的故障.

但请注意,对于明确描述为始终成功的函数(例如getpid()),不会出现此情况.

感谢@rici指针

ERANGE更像是不适合这种情况.strtol()就是一个例子.另一个不那么清楚:尝试增加SYSV信号量超过其配置的限制返回ERANGE.

有了EOVERFLOW这些数据,它就不适合本地数据结构.

例如,lseek()可以返回EOVERFLOW.发生这种情况,例如,当off_t只有32位但文件系统可以支持更大的文件,并且您尝试超出操作系统可以处理的范围.这不是为什么ERANGE?由于系统原则上可以处理操作,因此无法以可用的数据类型将其返回给您.

试图mmap()在Linux上的32位系统上使用2G以上的映射返回EOVERFLOW(其他系统返回EINVAL).

不幸的是,这并不完全一致.例如,蓝牙堆栈EOVERFLOW在系统中找到太多主机控制器时返回.