Unix 接口是用 C 语言描述的,但同样重要的是系统有一个 ABI,而不仅仅是一个 API。
特定于编程语言的奇特数据结构使 ABI 复杂化。在 ABI 级别,您只有低级别的数据类型,如“32 位无符号整数”及其简单聚合。
话虽如此,Unix 接口确实使用了pid_t
诸如此类之类的类型,那么为什么不将这些 typedef 之一用于文件描述符呢?
文件描述符具有某些众所周知的值,当打开一个新的文件描述符时,总是使用可用的最小正值。文件描述符值有效地充当描述符表中的数组索引,并且设计是故意的。程序员的文件描述符模型是它们在内核中有类似数组的结构。该dup2
函数实际上可以将文件描述符从一个插槽复制到另一个插槽。这样的数组索引也可能是int
,对于信号错误具有负值。
C typedefs 不购买额外的类型检查,但它们确实带来了一点可读性和抽象性:独立于特定的整数类型。一个fd_t
类型可以是int
一个系统上的一个和long
另一个系统上的一个。但是由于int
几十年前已经发展到几乎无处不在的 32 位宽,因此没有真正需要为了能够在同名下使其更宽而对其进行抽象。一个程序需要超过 20 亿个打开的文件描述符是非常不寻常的。
相比之下,如果使用纯文本int
而不是pthread_t
.
int
对于 Windows Socket API 的设计者来说,描述符确实难以接受,他们发明了SOCKET
typedef,其值不是可用的最低正整数;只是导致便携性烦恼的怪癖之一。但是,依赖这些描述符的代码存在真正的语义差异,这些描述符是一个范围内的小值,要么不起作用,要么表现低效。
有一些历史上的 Unix 实例已被修改为int
用一些 typedef 替换普通类型。例如,在一个accept
函数中,远程地址结构的大小过去只是int
. 然后就变成了socklen_t
。没有存在的技术需求socklen_t
;它被发明为一种创可贴的解决方案,以弥合使用传统系统的系统int
与维护者热心改变使用论点的系统之间的差异size_t
。虽然这两种类型导致相同的 ABI,但没有问题,直到具有 64 位size_t
和 32 位的系统int
。