问说真的,有没有实际的机器真正使用过非零的空指针,或者对不同类型的指针使用不同的表示方式?
答Prime 50 系列至少对于 PL/I 使用 07777 段,偏移量 0 作为空指针。 后来的型号在 C 语言中使用 0 段,偏移量 0 作为空指针,因此需要新的指令,例如 TCNP(测试 C 空指针),显然是为了安抚 [脚注] 所有现存的编写糟糕的 C 代码,这些代码做出了不正确的假设。 较旧的、以字为寻址单位的 Prime 机器也因要求比字指针(char *)更大的字节指针(int *)而臭名昭著。
Data General 的 Eclipse MV 系列具有三种架构支持的指针格式(字指针、字节指针和位指针),C 编译器使用其中的两种:char *和void *使用字节指针,而其他所有内容都使用字指针。 由于 32 位 MV 产品线从 16 位 Nova 产品线发展而来的历史原因,字指针和字节指针在字中的偏移量、间接寻址和环保护位的位置不同。 将不匹配的指针格式传递给函数会导致保护错误。 最终,MV C 编译器添加了许多兼容性选项,试图处理具有指针类型不匹配错误的代码。
一些Honeywell-Bull大型机使用位模式 06000 作为(内部)空指针。
CDC Cyber 180 系列具有 48 位指针,由环、段和偏移量组成。 大多数用户(在环 11 中)的空指针为 0xB00000000000。 在旧的 CDC ones-complement 机器上,通常使用全 1 位字作为各种数据的特殊标志,包括无效地址。
旧的 HP 3000 系列对字节地址使用与字地址不同的寻址方案; 因此,与上述几台机器一样,它对char *和void *指针使用不同的表示形式。
Symbolics Lisp 机器是一种带标记的架构,甚至没有传统的数字指针; 它使用对<NIL, 0>(基本上是不存在的<对象, 偏移量>句柄)作为 C 空指针。
根据使用的“内存模型”,8086 系列处理器(PC 兼容机)可以使用 16 位数据指针和 32 位函数指针,反之亦然。
一些 64 位 Cray 机器将int *表示在一个字的低 48 位中;char *此外,还使用一些高 16 位来指示字内的字节地址。
更多链接:来自 Chris Torek 的 消息,其中包含有关其中一些机器的更多详细信息。
参考资料:K&R1 Sec. A14.4 p. 211