Smart pointers instead of GC?
Frank Bauer
y at z.com
Sun Feb 2 12:29:31 PST 2014
+1 on making Phobos GC-free.
On Sunday, 2 February 2014 at 07:35:21 UTC, Andrei Alexandrescu
wrote:
> On 2/1/14, 10:00 PM, Frank Bauer wrote:
>> On Sunday, 2 February 2014 at 05:41:53 UTC, Andrei
>> Alexandrescu wrote:
>>> Sure. While you're young typecheck this:
>>>
>>> class A {
>>> auto stuff() { ...; return this; }
>>> }
>>>
>>>
>>> Andrei
>>
>> It would be a Borrowed!A, I would say, no matter how an A is
>> allocated.
>> A GC!A, an ARC!A and an Owning!A convert equally well to a
>> Borrowed!A.
>> As long as the Borrowed!A is in use (i.e. scope) after stuff()
>> returns,
>> the A object must not be freed (compiler enforced). Would that
>> make sense?
>
> No.
>
> What I'm driving at is that right now the type is A, as is in a
> variety of other situations. It would be a whole different
> language that would be wholly incompatible with D.
>
>
> Andrei
Why is that? I propose the new memory regime to be 100%
compatible with all existing D code. It is way more powerful than
anything scope can do. And it seems a lot less work to me than
going through GC optimization and custom allocator tracing hell.
Let's see how far we can get if we require none of the existing D
code to break.
Example: this is current D code that runs unchanged and with the
same semantics under the new memory regime. GC(T) and Borrowed(T)
remain under the hood:
class A {
A foo() { return this; } // returns Borrowed!A
}
void main () {
A m1 = new A; // m1 is a GC!A
A m2 = m1; // m2 is a Borrowed!A
A m3; // Borrowed!A
m3 = m1; // fine: assignment from GC!A to Borrowed!A
m3 = bar(m1); // fine: m1 converted from GC!A to
Borrowed!A, assignment from Borrowed!A to Borrowed!A
m3 = bar(m2); // fine: m2 already Borrowed!A, assignment
from Borrowed!A to Borrowed!A
m1 = new A; // fine: can reasssign GC!A although there
are outstanding references
m1 = m2; // fine: can reassign GC!A to a Borrowed!A
}
A bar(A a) { // takes and returns Borrowed!A
A b1 = a;
return b1;
}
Now here it comes: if, on the other hand, I replace the first
'new' with, say e.g., 'newOwning' (or '~', whatever), I get
GC-free code:
A m1 = newOwning A; // m1 is an Owning!A, allocating on the heap
and freeing when it goes out of scope
Then these lines above would be in error:
m1 = new A; // error: can't reassign to m1 because m2 and
m3 still referencing m1 (same for newOwning)
m1 = m2; // error: can't assign Borrowed!A to Owning!A
ARC(T) could be implemented similarly.
Nothing changes one bit for those who want to use the GC as
before. ARC(T) and Owning(T) would be *ADDED* on top of the
existing language spec.
Emplacement new, as Adam mentioned, is not a problem: you always
get to the emplaced object with a Borrowed!T. The underlying
memory is managed separately and automatically as a GC!M, ARC!M
or Owning!M (M could be an array of bytes, e.g.).
More information about the Digitalmars-d
mailing list