对于复杂的程序(例如,递归或可变大小的数据结构),某种间接是必需的。但是,没有必要通过指针实现此间接。
大多数高级编程语言(即非Assembly)都是相当内存安全的,并且不允许无限制的指针访问。C族在这里很奇怪。
C是从B演变而来的,这是对原始程序集的非常抽象的抽象。B有一个类型:单词。该词可以用作整数或指针。当整个内存被视为单个连续数组时,这两个等效。C保留了这种相当灵活的方法,并继续支持固有的不安全指针算法。C的整个类型系统更像是事后的想法。这种对内存访问的灵活性使C非常适合其主要用途:对Unix操作系统进行原型设计。当然,事实证明Unix和C非常流行,因此在实际上不需要这种低级内存方法的应用程序中也使用C。
如果我们看一下C之前的编程语言(例如Fortran,Algol方言,包括Pascal,Cobol,Lisp等),其中某些确实支持C指针。值得注意的是,空指针概念是1965年为Algol W发明的。但是,这些语言都没有尝试成为类似C的高效低抽象系统语言:Fortran是用于科学计算的,Algol开发了一些相当高级的概念,Lisp是与行业级语言相比,它更多的是研究项目,而Cobol则专注于业务应用程序。
垃圾收集自50年代末开始存在,即早于C(70年代初)。GC需要内存安全才能正常工作。C之前和之后的语言均使用GC作为正常功能。当然,这会使语言变得复杂得多,甚至可能变慢,这在大型机时代尤其明显。GC语言倾向于以研究为导向(例如Lisp,Simula,ML)和/或需要功能强大的工作站(例如Smalltalk)。
随着更小,功能更强大的计算机在通用语言和GC语言中的特殊应用,确实变得越来越流行。对于非实时应用程序(有时甚至是那时),GC现在是首选方法。但是GC算法也一直是深入研究的主题。作为替代方案,在没有GC的情况下,还进一步开发了更好的内存安全性,尤其是在最近的三十年中:值得注意的创新是RAII和C ++中的智能指针以及Rust的生命周期系统/借用检查器。
Java并不是通过内存安全的编程语言进行创新的:它基本上采用了GCed的语义,内存安全的Smalltalk语言,并将它们与C ++的语法和静态类型结合在一起。然后将其作为更好,更简单的C / C ++进行销售。但这只是表面上的C ++后代。Java缺少指针的原因更多是因为Smalltalk对象模型而不是C ++数据模型被拒绝。
因此,不应将Java,Ruby和C#等“现代”语言解释为克服C语言中的原始指针问题,而应将其视为许多传统的借鉴,包括C语言,还应借鉴更安全的语言,例如Smalltalk,Simula,或Lisp。