42

C++11 的语言特性列表中有:

对垃圾收集和基于可达性的泄漏检测的最小支持

(但它似乎没有在 GCC 和 Clang 中实现。)

为什么标准委员会引入了这种垃圾收集 C++ 语言特性?

C++ 真的需要 GC 吗?RAII 不是这么优秀的模式吗(可以统一用于内存和非内存资源,如套接字、文件、纹理......)?

GC 会破坏使用 RAII 的 C++ 代码模式的一致性吗?

有人说 GC 可以派上用场来打破循环依赖关系,但是weak_ptr为此目的使用智能指针不就可以了吗?

如果抛出异常会发生什么?如何修改堆栈展开语义以考虑 GC?

IDisposable还会引入类似C# 的模式吗?

而且,假设C++中引入了GC,指针语法会不会不一样?^例如,在 C++/CLI 或 C++/CX 扩展中,我们会不会有一些类似帽子的“指针” ?应该有一种方法可以区分普通的原始指针和“托管”指针,对吧?

4

3 回答 3

59

该提案没有引入垃圾收集器 -如果实现选择,它只是在某些情况下允许它。该标准只会将这些情况描述为导致未定义的行为。在这样做时,它放宽了实现的要求,为垃圾收集器提供了最小的余地。

提案中给出的简单示例考虑了当您将指针指向动态分配的对象时,将其与另一个值进行异或,从而隐藏指针值,然后恢复原始指针值以通过它访问对象。在 C++11 之前,这将非常好,并且仍然可以使用。然而,现在这样的操作可能(见下一段)被认为是未定义的行为,这意味着实现可以对所指向的对象进行垃圾收集。

该标准规定,实现可以具有宽松的指针安全性,在这种情况下行为与以前一样,或者具有严格的指针安全性,这允许引入垃圾收集器。

实现可能放宽了指针安全性,在这种情况下,指针值的有效性不取决于它是否是安全派生的指针值。或者,实现可能具有严格的指针安全性,在这种情况下,不是安全派生的指针值的指针值是无效的指针值,除非引用的完整对象具有动态存储持续时间并且之前已被声明为可访问(20.6.4 )。[...]实现定义了实现是否具有宽松或严格的指针安全性。

如果指针值指向动态分配的对象并且没有发生任何有趣的事情(在 §3.7.4.3 中更具体地定义),则指针值是安全派生的指针值。

如果您的实现具有严格的指针安全性,但您仍想对指针进行上述有趣的业务而不引入未定义的行为,则可以将指针声明p为可访问,如下所示:

declare_reachable(p);

<memory>此函数与相关函数(如 、 和 )一起undeclare_reachable定义declare_no_pointers在标题中undeclare_no_pointers。您还可以使用get_pointer_safety.

于 2013-03-01T12:22:12.177 回答
20

来自 Bjarne Stroustrup:

实际上,我所说的类似于“当(不是如果)自动垃圾收集成为 C++ 的一部分时,它将是可选的”。

http://www.stroustrup.com/slashdot_interview.html

于 2013-03-01T12:26:24.397 回答
1

有一个建议从标准中删除此 GC 支持:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2186r0.html

并且有一个 C++ GC(Boehm): https ://www.hboehm.info/gc/

于 2020-12-08T12:22:24.833 回答