Possible @property compromise

TommiT tommitissari at hotmail.com
Sat Feb 2 10:04:28 PST 2013


On Saturday, 2 February 2013 at 17:49:44 UTC, Zach the Mystic 
wrote:
> On Saturday, 2 February 2013 at 07:10:00 UTC, TommiT wrote:
>> On Saturday, 2 February 2013 at 03:50:49 UTC, Zach the Mystic 
>> wrote:
>>> [..]
>>
>> Then, if we used your proposed nested structs to implement 
>> properties, pretty weird things like this would become 
>> possible:
>>
>> struct A
>> {
>>  int _value;
>>
>>  struct B
>>  {
>>    int get() { return _value; }
>>    alias this = get;
>>
>>    void opAssign(int v) { _value = v; }
>>  }
>>
>>  B length;
>> }
>>
>> void func(T)(ref A a, T oldLength)
>> {
>>  a.length = 100;
>>  // Trying to restore 'a' back to the old length:
>>  a.length = oldLength;
>> }
>>
>> void main()
>> {
>>  A a;
>>  a.length = 5;
>>  func(a, a.length);
>>  assert(a.length == 100);
>> }
>
> This code is both wrong and has nothing whatever to do with the 
> current topic. Boiling down the template to its resulting 
> function, and imagining _value as the intended entity:
>
> void func(ref A a, int oldLength)
> {
>   a._value = 100;
>   a._value = oldLength;
> }
> A a;
> a._value = 5;
> func(a, a._value);
> assert(a._value == 5); // 5, not 100
>
> func takes an int. It's not a reference, it's a copy.
>
> Let's assume you meant void func(ref A a, ref int oldLength) {} 
> instead. Well, if you pass a reference, set it, and then refer 
> it, you're going to get the set value back. I'm sorry, you 
> can't adjust a reference and then expect to get a phantom 
> original copy back. While I may have made a mistake, I simply 
> see no connection between this and the idea of properties as 
> structs.

No, you're not getting it. The following is a function template:

void func(T)(ref A a, T oldLength) {...}

The type of parameter oldLength is going to be the type of the 
expression you pass as the second argument when you call func. If 
you call func like I did in my example:

A a;
func(a, a.length);

...the type of the second argument to func, a.length, is A.B, and 
therefore the specialization of func that ends up being called is:

void func(ref A a, A.B oldLength) {...}

...and variable a.length is being passed by value, not by 
reference.


More information about the Digitalmars-d mailing list