DIP77 - Fix unsafe RC pass by 'ref'
w0rp via Digitalmars-d
digitalmars-d at puremagic.com
Sat Apr 11 03:13:59 PDT 2015
On Saturday, 11 April 2015 at 09:28:46 UTC, Marc Schütz wrote:
> On Friday, 10 April 2015 at 23:12:55 UTC, deadalnix wrote:
>> On Friday, 10 April 2015 at 10:02:01 UTC, Martin Nowak wrote:
>>> On Wednesday, 8 April 2015 at 23:11:08 UTC, Walter Bright
>>> wrote:
>>>> http://wiki.dlang.org/DIP77
>>>
>>> So someone passes an RCO via ref to avoid the inc/dec, and
>>> because that imposes safety issues we turn it into some sort
>>> of pass by value under the hood, defeating the purpose, and
>>> provide an opt-out via @system opAssign.
>>>
>>> Wouldn't it more straightforward to make pass-by-ref unsafe
>>> (@system) for RCOs?
>>>
>>> Then the only thing missing to make this equally powerful,
>>> would be an optimization opportunity for the compiler to
>>> elide copies of pass-by-value RCOs, e.g. it could avoid
>>> calling the postblit when the function retains the refcount.
>>
>> Only the first pass by ref create a copy. You can then pass
>> the ref down all you want without copy.
>>
>> That is an acceptable cost IMO.
>
> It's not acceptable that it happens behind the user's back.
> Costly operations must be explicit.
If we somehow know for a fact that the object really is a
reference counted object, then the cost should be acceptable.
Running the postblit will consist of incrementing a reference
count and nothing else. There's no other way I can think of that
permits passing the object safely.
I think the one thing in the DIP I'm not sure of is the
definition of what is a reference counted object. Say you write
this.
struct Widget {
byte* data;
size_t length;
@trusted
opAssign(ref const(Widget) other) {
length = other.length;
data = malloc(length);
memcpy(cast(void*) data, cast(void*) other.data, length);
}
@trusted
this(this) {
auto oldData = data;
data = malloc(length);
memcpy(cast(void*) data, cast(void*) oldData, length);
}
@trusted
~this() {
free(data);
}
}
Why would you want to do this? Who knows. According to DIP77 the
object above is defined to be a reference counted object, when it
isn't. If we're rejecting the C++ answer of "don't write code
that way," then the same rejection should apply here. We need to
be able to say with 100% certainty that we are dealing with a
reference counted object, or at least an object where we know the
postblit is so trivial the cost of calling it will be small.
More information about the Digitalmars-d
mailing list