简体   繁体   English

C++11 垃圾收集器 - 为什么和如何

[英]C++11 Garbage Collector - Why and Hows

In C++11's language feature list there is:C++11 的语言特性列表中有:

Minimal support for garbage collection and reachability-based leak detection对垃圾收集和基于可达性的泄漏检测的最小支持

(but it seems not implemented in either GCC and Clang.) (但它似乎没有在 GCC 和 Clang 中实现。)

Why the standard committee introduced this garbage collection C++ langauge feature?为什么标准委员会要引入这个垃圾回收 C++ 语言特性?

Does C++ really need a GC? C++真的需要GC吗? Isn't RAII such an excellent pattern (that can be used uniformly for both memory and non-memory resources, like sockets, files, textures...)? RAII 是不是这样一种优秀的模式(可以统一用于内存和非内存资源,如套接字、文件、纹理......)?

Will a GC break the uniformity of C++ code pattern that uses RAII? GC 会破坏使用 RAII 的 C++ 代码模式的统一性吗?

Some people say that a GC can come in handy to break circular dependencies, but isn't it just OK to use smart pointers like weak_ptr for this purpose?有人说 GC 可以派上用场来打破循环依赖,但为此目的使用像weak_ptr这样的智能指针不就可以了吗?

And what happens in case of exceptions thrown?如果抛出异常会发生什么? How will the stack unwind semantics be modified to take a GC into consideration?如何修改堆栈展开语义以考虑 GC?

And will a C#-like IDisposable pattern be introduced as well?是否还会引入类似 C# 的IDisposable模式?

Moreover, assuming that a GC is introduced in C++, will the pointer syntax be different?而且,假设在C++中引入了GC,指针语法会有所不同吗? eg Will we have some hat-like "pointers" ^ like in C++/CLI or C++/CX extensions?例如,在 C++/CLI 或 C++/CX 扩展中,我们是否会有一些类似帽子的“指针” ^ There should be a way to differentiate from ordinary raw pointers vs. "managed" pointers, right?应该有办法区分普通原始指针与“托管”指针,对吗?

The proposal doesn't introduce a garbage collector - it just allows for it in certain situations if the implementation chooses .该提案没有引入垃圾收集器 -如果实现选择,它只是在某些情况下允许它。 The standard will just describe these situations as causing undefined behaviour.该标准只会将这些情况描述为导致未定义行为。 In doing this, it relaxes the requirements of the implementation, giving the minimal leeway for a garbage collector.在这样做时,它放宽了实现的要求,为垃圾收集器提供了最小的回旋余地。

The simple example given in the proposal considers when you take a pointer to a dynamically allocated object, XOR it with another value, thereby hiding the pointer value, and then recover the original pointer value to access the object through it. 提案中给出的简单例子考虑了当你拿一个指向动态分配对象的指针时,将它与另一个值进行异或,从而隐藏该指针值,然后恢复原始指针值以通过它访问该对象。 Before C++11, this would be perfectly fine and it would still be valid to use.在 C++11 之前,这完全没问题,并且仍然可以使用。 However, now such an operation may be (see next paragraph) considered undefined behaviour, which means that an implementation may do garbage collection on the object that was pointed to.然而,现在这样的操作可能(见下一段)被认为是未定义的行为,这意味着一个实现可能会对指向的对象进行垃圾收集。

The standard states that an implementation can either have relaxed pointer safety , in which case the behaviour is as it was before, or strict pointer safety , which allows for the introduction of a garbage collector.该标准规定,实现可以具有宽松的指针安全性,在这种情况下,行为与以前一样,或者具有严格的指针安全性,允许引入垃圾收集器。

An implementation may have relaxed pointer safety , in which case the validity of a pointer value does not depend on whether it is a safely-derived pointer value.实现可能放宽了指针安全性,在这种情况下,指针值的有效性不取决于它是否是安全派生的指针值。 Alternatively, an implementation may have strict pointer safety , in which case a pointer value that is not a safely-derived pointer value is an invalid pointer value unless the referenced complete object is of dynamic storage duration and has previously been declared reachable (20.6.4).或者,实现可能具有严格的指针安全性,在这种情况下,不是安全派生指针值的指针值是无效指针值,除非引用的完整对象具有动态存储持续时间并且之前已声明可达(20.6.4 )。 [...] It is implementation defined whether an implementation has relaxed or strict pointer safety. [...] 实现定义了实现是否具有宽松或严格的指针安全性。

A pointer value is a safely-derived pointer value if it points at a dynamically allocated object and hasn't had any funny business happen to it (defined more specifically in §3.7.4.3).如果指针值指向动态分配的对象并且没有发生任何有趣的事情(在 §3.7.4.3 中更具体地定义),则该指针值是安全派生的指针值。

If your implementation has strict pointer safety yet you still want to do said funny business to a pointer without introducing undefined behaviour, you can declare a pointer p as being reachable like so:如果您的实现具有严格的指针安全性,但您仍然希望在不引入未定义行为的情况下对指针执行上述有趣的操作,则可以像这样声明指针p是可访问的:

declare_reachable(p);

This function is defined in the <memory> header, along with related functions such as undeclare_reachable , declare_no_pointers , and undeclare_no_pointers .这个功能是在所定义的<memory>头,具有相关功能,例如沿undeclare_reachabledeclare_no_pointers ,和undeclare_no_pointers You can also determine the strictness of your implementation using get_pointer_safety .您还可以使用get_pointer_safety确定实现的严格性。

From Bjarne Stroustrup:来自 Bjarne Stroustrup:

Actually, what I said was something like "When (not if) automatic garbage collection becomes part of C++, it will be optional".实际上,我所说的类似于“当(不是如果)自动垃圾收集成为 C++ 的一部分时,它将是可选的”。

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

There is a proposal to remove this GC support from standard:有一项建议从标准中删除此 GC 支持:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM