On Apr 4, 7:32 am, Jon Harrop <j...@ffconsultancy.com> wrote:
Chris Thomasson wrote:
Now I have another question for you; given:
0: Bar* bar(gc_new Bar);
How could a valid GC collect bar while g() is executing when there is a
live pointer to the Bar object 'bar var' created on 'line 0'? In order for
a GC to make a collection to the object that the variable bar points to
you would need to either drop out of the scope, or explicitly set bar to
NULL before g() is called.
0: Bar* bar(gc_new Bar);
2: bar = NULL;
Therefore, your example is busted on multiple levels. Sorry. I would
advise that you learn how GC actually works.
Excellent! You are now moving towards the correct way of looking at this.
You are basically saying that a GC should not be able to collect "bar"
because it is still in scope.
GC will not collect an object as long as there are live references to
it. Scope never had anything to do with it. Do you think the "using"
block in C# relies on scope?
You are correct that "bar" is in scope. However, GCs collect unreachable
values and scope has nothing to do with reachability.
... unreachable values are collected **only** when the GC is triggered
and you **never** know when that can happen. As a result the object
may be unreachable but its still hanging out there. This is the non-
determinism Chris has been trying to ram on you for the past, uh,
several million posts.
Scope is simply the
way we lay out source code. Reachability refers to whether or not global
roots (e.g. pointers on the stack or in registers) can follow a dependency
path through a snapshot of the heap at any given moment in time to reach a
given value. If there is no path from the roots to a given value then that
value is unreachable by definition. Note that this has absolutely nothing
to do with scope.
No one ever disputed any of this. In fact if you re-read (i.e if you
even bothered to read them in the first place) some of Jerry Coffin's
posts he says exactly this. Sounds like a straw-man to me.
It is precisely this discrepancy between scope and reachability that makes
reference counting keep values alive unnecessarily.
what do you mean?
ISomeType* obj = CoCreateInstance(....); // this api does the
// do a lot of stuff here...
A properly written Release function will destroy obj right at that
point which is ref-counting done the COM way. are you saying obj is
kept alive until the end of the block? That might happen only if you
wrap ISomeType in some kind of smart pointer which will call Release
at the end of the block -- but I am not doing that here.
You are also correct that we can manually work around the problem of "bar"
being artificially kept alive during the call to "g()" by adding a new
nested scope. However, there are two problems with your solution:
1. This still isn't necessarily collecting "bar" as early as possible
because it may well become unreachable during the call to "f".
so what? being unreachable does not mean a GC will collect it right
away? in that sense its still being kept alive.
2. There still exists code (e.g. my example) where reference counting keeps
values alive unnecessarily.
How in the God's name can that be possible? Either you call an
explicit API that will decrement the ref-count or you wire up the dtor
in such a way that an end-of-scope takes care of such decrements. In
both cases, 0 means blow the object out of the water.
In fact, you can persue your idea further and try to always deallocate
values at the earliest opportunity. However, this culminates in a technique
called regioning that makes no use of reference counts and, consequently,
cannot be classified as a reference counting algorithm.
Regioning? Did you just pull that word out of your hat? Can you pass
me any links or papers mentioning such a concept?