首先我们要明确什么是垃圾。
Java 对垃圾的定义是不再可达的对象。可达性的精确含义有点深奥,但一个实用的定义是,如果您可以通过跟踪线程堆栈或静态变量等众所周知的地方的引用(指针)来访问对象,那么它可能是可达的。(实际上,一些不精确是可以的,只要可到达的对象不会被删除。)
您可以尝试将相同的定义应用于 C 和 C++。如果一个对象无法被访问,那么它就是垃圾。
然而,在 C 或 C++ 中这个定义……和垃圾收集……的实际问题是“类似指针”的值是否实际上是一个有效的指针。例如:
union类型用 覆盖指针时long,垃圾收集器无法确定联合是否包含其中一个或另一个……或两者。 然而,很明显,C 程序可以调用malloc,忘记调用free,然后忘记堆节点的地址。那个节点是垃圾。
C/C++ 没有垃圾回收有两个原因。
这是“文化上不合适的”。这些语言的文化是将存储管理留给程序员。
为 C / C++ 实现精确的垃圾收集器在技术上是困难的(而且昂贵)。事实上,这样做会导致语言实现变慢。
不精确(即保守)的垃圾收集器很实用,但它们存在性能和(我听说)可靠性问题。(例如,保守的收集器无法移动非垃圾对象。)
如果(C / C ++垃圾收集器的)实现者可以假设程序员只编写严格符合C / C ++规范的代码,那就更简单了。但他们没有。
但你的答案似乎是,为什么他们要这样设计C?
诸如此类的问题只能由设计师(在本例中为已故的丹尼斯·里奇)或他们的著作来权威回答。
正如您在问题中指出的那样,C 的设计是简单且“接近硬件”。
然而,C 是在 20 世纪 70 年代初设计的。那时,需要垃圾收集器的编程语言很少见,GC 技术也不像现在那么先进。
即使现在,垃圾收集语言(如 Java)仍然不适合需要可预测的“实时”性能的应用程序,这仍然是一个事实。
简而言之,我怀疑设计者认为垃圾收集会使该语言无法实现其预期目的。