On Wednesday, 20 December 2017 at 00:38:58 UTC, Jonathan M Davis
wrote:
On Tuesday, December 19, 2017 23:53:04 bachmeier via
Digitalmars-d wrote:
On Tuesday, 19 December 2017 at 13:14:50 UTC, Mark wrote:
> What do you think of the following comment to that article?
>
> "In well-written modern C++, memory management errors are a
> solved problem. You can just write code, and know that the
> compiler and library will take care of cleaning up for you,
> just like with a GC-based system, but with the added benefit
> that it’s deterministic, and can handle non-memory resources
> such as file handles and sockets too."
I'm no C++ expert, but isn't that because of the use of unique
pointers and shared pointers? And aren't shared pointers
reference counted and stuck with the usual limitations
associated with reference counting?
What limitations are you concerned about? Certainly, shared_ptr
comes with whatever pros and cons come from non-intrusive (i.e.
not built into the object) reference-counting, but from I've
seen, there really isn't much of a downside to them
(_especially_ if you're comparing them to manual memory
management). Mostly, you just have to worry about using
weak_ptr when you'd otherwise have a circular reference. Sure,
using the GC is easier but not by much. In my experience, you
can generally just use shared_ptr and not worry much about
memory management, and you get mostly deterministic
destruction, unlike the GC (it's mostly, because there are
times when stuff sticks around a lot longer than you might
expect, because something has a reference to it, which isn't
always obvious; it's still technically determinstic, but the
effect can seem pretty non-deterministic sometimes). There are
plenty of C++ programmers who have no problem with shared_ptr
who would feel quite leery about using the GC, and for some
stuff, the determinism of reference counting can be critical.
With a GC, you can mostly not worry about such things, but
occasionally, you have to be careful, or you'll have problems
with resource management because on the non-determinism (e.g.
you really don't want sockets to closed based on when the GC
collects the socket object). And whether RC or GC is better for
performance depends heavily on what you're doing. RC tends to
slow everything down slightly but usually doesn't have bursts
of memory collection (though it can when you free a large tree
of objects at once), whereas the GC doesn't slow stuff down as
it goes along, but it has definite bursts where performance
tanks, because a collection is being run. I'd say that from D's
perspective, the main advantage of the GC over RC is that the
compiler can guarantee that it's @safe, which is more more
problematic with RC - that and you don't have to worry about
circular references with the GC like you do with RC.
Overally, I don't think that it's particularly clearcut whether
RC or GC is better overall. The big thing is that the memory is
managed automatically rather than manually.
That's what I'm getting at. The comment shared by Mark does not
contradict the blog post. The C++ community gave up on manual
memory management, just taking a different route to automatic
memory management, with the associated costs and benefits.