Using ()s in @property functions

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Jun 29 22:32:24 PDT 2010


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".

Indeed properties with separate get and set that don't expose references 
are quite different from fields. Those that return ref are more similar 
to fields. The basic goal is to bring both as close as possible to field 
syntax and semantics.

Andrei


More information about the Digitalmars-d mailing list