Using ()s in @property functions

Chad J chadjoan at __spam.is.bad__gmail.com
Tue Jun 29 22:00:53 PDT 2010


On 06/30/2010 12:33 AM, Robert Jacques wrote:
> On Tue, 29 Jun 2010 23:41:48 -0400, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
> .
>> Robert Jacques wrote:
>>> On Tue, 29 Jun 2010 11:44:07 -0400, Andrei Alexandrescu
>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>
>>>> Steven Schveighoffer wrote:
>>>>> On Tue, 29 Jun 2010 10:15:10 -0400, Leandro Lucarella
>>>>> <luca at llucax.com.ar> wrote:
>>>>>
>>>>>> Steven Schveighoffer, el 29 de junio a las 08:13 me escribiste:
>>>>>>> >>There is one thing that bugs me about this solution though. 
>>>>>>> What if the
>>>>>>> >>user does this:
>>>>>>> >>(1) Grab the pointer.  *ptr = prop;
>>>>>>> >(1) Grab the pointer.  T* ptr = &prop;
>>>>>>> >
>>>>>>> >>(2) assigns to it.  *ptr = val;
>>>>>>> >>(3) expects the result to be updated in prop.  assert(val ==
>>>>>>> prop);
>>>>>>> >
>>>>>>>
>>>>>>> Why would this assert fail?  If a property returns a ref
>>>>>>
>>>>>> What if it doesn't? If returns a temporary calculated value?
>>>>>  It returns a ref.  That can't be a calculated value.  If it's a
>>>>> calculated value then T* ptr = &prop will fail to compile.
>>>>
>>>> It's a "calculated reference", e.g. several instances could share
>>>> the same value etc. Once the reference is out, clearly there's no
>>>> more control.
>>>>
>>>> I agree with the view that a @property returning ref should be
>>>> virtually indistinguishable from a field. Currently that's not the
>>>> case, e.g. if you want to assign to such a property you must add
>>>> parens:
>>>>
>>>> struct A { int x; @property ref y() { return x; } }
>>>>
>>>> unittest
>>>> {
>>>>      A a;
>>>>      a.y = 5; // fails
>>>>      a.y() = 5; // works
>>>> }
>>>>
>>>>
>>>> Andrei
>>>  Okay, but what about non-ref properties? i.e.
>>>  struct A {
>>>    int x;
>>>    @property int y()      { return x; }
>>>    @property int y(int v) { return x = v; }
>>> }
>>>  unittest {
>>>    A a;
>>>    int* ptr = &a.x; // works
>>>    int* ptr = &a.y; // fails
>>> }
>>>  Is there a good way of patching this leak in the @property abstraction?
>>
>> I don't think you should be able to even take the address of a non-ref
>> property.
>>
>> Andrei
> 
> I agree with you from a under-the-hood perspective, but I wasn't asking
> about that. I was asking about the leak in the @property abstraction.
> Not being able to pass non-ref @properties to functions by ref is a
> fairly serious (i.e. common) break/leak in the @property abstraction:
> that @properties should be "virtually indistinguishable from a field".

ref parameters are easily handled by property expression rewriting:

void foo( ref bar ) { ... }

foo(prop)

becomes

auto t = prop()
foo(t)
prop(t)

I would handle "out" parameters similarly, but without calling the
getter.  They are essentially a different way of writing an assignment.

Taking the /address/ is a bit different, since there may be no
well-defined line of code at which the pointer holding the address dies.
 The ref parameter, on the other hand, WILL expire when the function
returns.


More information about the Digitalmars-d mailing list