为什么C不需要垃圾收集器?

Tac*_*B0t 2 c garbage-collection

我对此的理解归结为 C 的起源作为“便携式汇编器”和更少开销的选择。这就是全部内容了吗?

Ste*_*n C 5

首先我们要明确什么是垃圾。

Java 对垃圾的定义是不再可达的对象。可达性的精确含义有点深奥,但一个实用的定义是,如果您可以通过跟踪线程堆栈或静态变量等众所周知的地方的引用(指针)来访问对象,那么它可能是可达的。(实际上,一些不精确是可以的,只要可到达的对象不会被删除。)

您可以尝试将相同的定义应用于 C 和 C++。如果一个对象无法被访问,那么它就是垃圾。

然而,在 C 或 C++ 中这个定义……和垃圾收集……的实际问题是“类似指针”的值是否实际上是一个有效的指针。例如:

  • 未初始化的 C 变量可以包含一个看起来像指向对象的指针的随机值。
  • 当 Cunion类型用 覆盖指针时long,垃圾收集器无法确定联合是否包含其中一个或另一个……或两者。
  • 当 C 应用程序代码通过将指向字对齐堆节点的指针除以 4 或 8 来“压缩”它们时,垃圾收集器不会将它们检测为“类似指针”。或者如果确实如此,它也会误解它们。
  • 类似的问题是当 C 应用程序代码将指针表示为相对于其他内容的偏移量时。

然而,很明显,C 程序可以调用malloc,忘记调用free,然后忘记堆节点的地址。那个节点是垃圾。


C/C++ 没有垃圾回收有两个原因。

  • 这是“文化上不合适的”。这些语言的文化是将存储管理留给程序员。

  • 为 C / C++ 实现精确的垃圾收集器在技术上是困难的(而且昂贵)。事实上,这样做会导致语言实现变慢。

  • 不精确(即保守)的垃圾收集器很实用,但它们存在性能和(我听说)可靠性问题。(例如,保守的收集器无法移动非垃圾对象。)

如果(C / C ++垃圾收集器的)实现者可以假设程序员只编写严格符合C / C ++规范的代码,那就更简单了。但他们没有。


但你的答案似乎是,为什么他们要这样设计C?

诸如此类的问题只能由设计师(在本例中为已故的丹尼斯·里奇)或他们的著作来权威回答。

正如您在问题中指出的那样,C 的设计简单且“接近硬件”。

然而,C 是在 20 世纪 70 年代初设计的。那时,需要垃圾收集器的编程语言很少见,GC 技术也不像现在那么先进。

即使现在,垃圾收集语言(如 Java)仍然不适合需要可预测的“实时”性能的应用程序,这仍然是一个事实。

简而言之,我怀疑设计者认为垃圾收集会使该语言无法实现其预期目的。

  • 问题列表不完整。现实生活中的示例:C 代码获取已分配内存的指针,将其除以四,并将其存储到一个结构中,该结构必须与某些旧的 bcpl 代码(或必须使用该结构进行相同操作的其他 C 代码)保持向后兼容。原因)。每当需要访问内存时,在访问之前将该值乘以四,否则,实际的指针永远不会出现在内存中。其他示例,指向某个结构的指针始终指向某个嵌入结构,分配的内存始终在此之前开始一个已知的偏移量 (2认同)