Properties: a.b.c = 3

Chad J chadjoan at __spam.is.bad__gmail.com
Fri Jul 31 01:01:22 PDT 2009


Jarrett Billingsley wrote:
> On Wed, Jul 29, 2009 at 1:08 AM, Daniel Keep<daniel.keep.lists at gmail.com> wrote:
>>
>> Problem: what if .b is computed?  Take .length as an example; the setter
>> MUST be invoked when the length changes, or the stored value won't have
>> any bearing on the actual number of elements being stored.
> 
> That's not the issue at hand.  The issue is that the compiler accepts
> no-effect modifications of temporary values as valid statements.
> There is no setter being invoked here, nor should there be.
> 
> Or should there?  In the face of a value type, should the compiler
> rewrite this code as
> 
> auto t = a.b();
> t.c = 3;
> a.b = t;
> 
> ?  The last line of the rewrite is unnecessary if a.b() returns a
> reference type or a byref struct.  But is this what people would
> expect to happen?
> 

I believe it is.

Note what happens if the user doesn't expect this:
Rather than the reference being set to the correct value, the reference
is set to the correct value.

Seems fine to me.

The only issue I see as being potentially bad is that if the coder
doesn't know about the rewrite rule and writes a non-trivial setter that
assumes that the incoming reference never was the outgoing reference.
It's kind of an odd assumption, and one that's bound to fail in other
cases too (where other cases is any time the caller explicitly reads
from the property and then ... and then writes the original back into it).

>> Returning refs only works if the property is just pretending to be a
>> field; in which case the correct solution is to use a field.
> 
> Not entirely; you can (for some value of 'can') return a struct that
> has overloaded opAssign to do nontrivial setters.  But that's kludgey
> and C++-y.

Yeah.  Does not want.



More information about the Digitalmars-d mailing list