question about the implementation of Variant
Kapps via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Jan 4 09:34:47 PST 2016
On Monday, 4 January 2016 at 09:13:25 UTC, Jonathan M Davis wrote:
> On Monday, January 04, 2016 07:30:50 aki via
> Digitalmars-d-learn wrote:
>> But wait, how does GC detect there still be a live reference to
>> the object Foo?
>> Because store is just a fix sized array of bytes.
>> ubyte[size] store;
>> GC cannot be aware of the reference, right?
>
> As I understand it, the GC doesn't actually care about whether
> something is a pointer when it tries to figure out whether
> something refers to something - or at least, it'll treat
> integers as if they were pointers so that if you tried to do
> something like
>
> size_t i;
> {
> auto p = new int(5);
> i = cast(size_t)p;
> }
> // GC will not collect p even if it runs now
>
> then the fact that i matches the value of the address that p
> points to is enough for the GC to not collect the memory
> pointed to by p, even if there are no longer any pointers
> referring to it. This prevents problems when you do stuff like
> cast pointers to integers to store their values (which normally
> is crazy but on rare occasions makes sense). The downside is
> that the GC then has to treat all integers as if they were
> pointers, so if you have an integer whose value happens to
> match that of a memory address in GC-allocated memory (a so
> called false pointer), then that memory won't be freed, even if
> nothing is really pointing to it anymore. Fortunately, however,
> false pointers are primarily limited to 32-bit programs, and
> 64-bit programs don't have that problem because of how large
> their address space is (but 32-bit programs which allocate most
> of their address space can definitely run into problems where
> memory that should be freed isn't thanks to false pointers).
>
> - Jonathan M Davis
That's only because we don't have a precise garbage collector and
can't be relied upon. It's more of a bug / limitation rather than
something to actually use.
In the case of std.variant, it's not just byte[size] store, it's
actually a union:
union
{
ubyte[size] store;
// conservatively mark the region as pointers
static if (size >= (void*).sizeof)
void*[size / (void*).sizeof] p;
}
Which tells the garbage collector that it may be pointers there,
making it valid even for precise garbage collectors (which would
have to conservatively handle such a union).
More information about the Digitalmars-d-learn
mailing list