Subject: Re: [boost] request for interest in a garbage collection library
From: Achilleas Margaritis (axilmar_at_[hidden])
Date: 2009-04-20 17:27:11
Simonson, Lucanus J wrote:
> Achilleas Margaritis wrote:
>>> Jumping in here, the problem is that having to mix GC code, which
>>> automatically releases memory in a non-deterministic way, and normal
>>> RAII destructor code, which releases all resources in a deterministic
>>> way, creates two different syntaxes in a C++ program. This would
>>> currently require the programmer to "know" which type of destruction
>>> belongs with which object.
>> I think the overhead of knowing which type of destruction belongs to
>> which object is minimal when compared to the overhead of manually
>> tracking memory. Resources like memory should be tracked by a GC,
>> resources like mutexes or files should be tracked by RAII.
>> What I like in C++ is that I can use the best of both worlds at the
>> same time.
> Really? Memory should be tracked by GC and not RAII? Why? The only reason GC is even acceptable for managing memory is because memory is a very plentiful resource in most systems. RAII covers 90% of cases of memory allocation and in the other 10% I don't find managing it manually to be too much of a burden, and if I wanted to be lazy I could use shared pointers to do the reference counting instead of using a GC library with equal extra effort. I don't want to be lazy, and I don't want to debug problems in code that mixes and matches GC and non-GC objects and leaves it very ambiguous whether someone forgot to call delete.
I agree with you. As I said above, and in the readme, I consider GC as a
complimentary solution to existing solutions.
The reason for using a GC is to be relieved from having to think about
potential referential cycles. One nasty problem is cycles inserted via
subclassing. There can go undetected very easily, especially if the
subclass containing the cycle is introduced indirectly (this is a
real-world issue that had happened to my company some times).
>> But gc'd objects are are not supposed to touch other gc'd objects in
>> their destructor (if you check the readme, I explicitly say that the
>> order of finalization is random). Is there a realistic need to call
>> another gc'd object from a destructor?
> Saying your documentation states that GC objects shouldn't manipulate GC objects in their destructors is all well and good, but that won't stop people from doing it, and it won't stop their code from working when they test it and breaking later when it is used. If you could enforce such a thing with a compilation error using some template meta-programming trick that would be mildly interesting, but just saying its not supported and letting everyone who won't bother to read the documentation find that out the hard way is not good design because it is error prone. Just because the problem can't be solved doesn't mean there isn't a real problem here.
I respectfully disagree with you. Solutions always come with trade offs.
For example, when using shared ptrs, one trade-off are referential cycles.
For the GC, the trade off is that destructors should not touch other
The problem can be solved partially. Since the GC knows where pointers
and objects are, it can find the root objects in the object graph and
start the finalization from those objects. If the boost community is
interested, I can code it.
The only case that is unsolvable is the case where there is a cycle,
since in that case it is not possible to tell where is the start of the
graph. In this case, the gc will have to take an arbitrary decision and
start the finalization from a random graph node.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk