[phobos] Fwd: Re: Ruling out arbitrary cost copy construction?

Michel Fortin michel.fortin at michelf.com
Tue Nov 2 10:47:48 PDT 2010


Le 2010-11-02 à 13:05, SHOO a écrit :

> (2010/10/31 12:57), Andrei Alexandrescu wrote:
>> I am highly interested in the opinion of Phobos contributors in the
>> matter of copy construction (just posted the message below).
>> 
>> Andrei
>> 
>> -------- Original Message --------
>> Subject: Re: Ruling out arbitrary cost copy construction?
>> Date: Sat, 30 Oct 2010 22:56:24 -0500
>> From: Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>
>> Newsgroups: digitalmars.D
>> 
>> On 10/30/2010 09:40 PM, Michel Fortin wrote:
>>> On 2010-10-30 20:49:38 -0400, Andrei Alexandrescu
>>> <SeeWebsiteForEmail at erdani.org> said:
>>> 
>>>> On 10/30/10 2:24 CDT, Don wrote:
>>>>> At the moment, I think it's impossible.
>>>>> Has anyone succesfully implemented refcounting in D? As long as bug
>>>>> 3516
>>>>> (Destructor not called on temporaries) remains open, it doesn't seem to
>>>>> be possible.
>>>>> Is that the only blocker, or are there others?
>>>> 
>>>> I managed to define and use RefCounted in Phobos. File also uses
>>>> hand-made reference counting. I think RefCounted is a pretty good
>>>> abstraction (unless it hits the bug you mentioned.)
>>> 
>>> I like the idea of RefCounted as a way to automatically make things
>>> reference counted.
>> 
>> Unfortunately it's only a semi-automated mechanism.
>> 
>>> But like File and many similar ref-counted structs, it has this race
>>> condition (bug 4624) when stored inside the GC heap. Currently, most of
>>> Phobos's ref-counted structs are race-free only when they reside on the
>>> stack or if your program has only one thread (because the GC doesn't
>>> spawn threads if I'm correct).
>>> 
>>> It's a little sad that the language doesn't prevent races in destructors
>>> (bug 4621).
>> 
>> I hope we're able to solve these implementation issues that can be seen
>> as independent from the decision at hand.
>> 
>> Walter and I discussed the matter again today and we're on the brink of
>> deciding that cheap copy construction is to be assumed. This simplifies
>> the language and the library a great deal, and makes it perfectly good
>> for 95% of the cases. For a minority of types, code would need to go
>> through extra hoops (e.g. COW, refcounting) to be compliant.
>> 
>> I'm looking for more feedback from the larger D community. This is a
>> very important decision that marks one of the largest departures from
>> the C++ style. Taking the wrong turn here could alienate many
>> programmers coming from C++.
>> 
>> So, everybody - this is really the time to speak up or forever be silent.
>> 
>> 
>> Andrei
> 
> Another viewpoint.
> 
> Is SealedRange really appropriate?
> 
> All these are caused by the same problem:
> - http://ideone.com/x1Zus
> - http://ideone.com/iM18Q
> - http://ideone.com/TTin3
> - http://ideone.com/x4b0o
> 
> We should consider that we grope the common solution for these problems.
> It is the method that block the access to reference data of which instance was deleted.

In first and second examples, you're taking the address of a local variable. This is forbidden in @safe code, so I consider this already solved.

In the third example, you're coping the sealed range into "r", then "ary" goes out of scope and delete the memory block while keeping a sealed range pointing to it. My take is that the implementation of Array is wrong: it should do *something* to either 1) prevent the sealed range from accessing the memory block, or 2) keep the memory block alive as long as a sealed range exists. Note that you can't write such an Array in @safe mode, and not using in @safe mode assumes you know what you're doing when it comes to handling memory. So I don't see that as a problem.

As for fourth example, it uses scope classes, which will be deprecated in D2.

Also take note that in second and third examples, the struct destructor is dangerous because it calls delete on a GC-allocated array "T[] a". As a general rule, you shouldn't access GC-allocated memory inside a destructor, this includes deleting it. That's because if you ever use this Array struct somewhere on the heap (like in a class), the GC could collect both the struct and the "T[] a" array at the same time, in whatever order, and you would calling the array's destructor twice (once by the GC + once in Array's destructor). But don't worry, you're not alone doing this mistake; I believe there is two instances of this in Phobos.


-- 
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/





More information about the phobos mailing list