Properties: a.b.c = 3
Jarrett Billingsley
jarrett.billingsley at gmail.com
Wed Jul 29 06:10:07 PDT 2009
On Wed, Jul 29, 2009 at 1:08 AM, Daniel Keep<daniel.keep.lists at gmail.com> wrote:
>
>
> Jarrett Billingsley wrote:
>> On Tue, Jul 28, 2009 at 10:33 PM, Walter
>> Bright<newshound1 at digitalmars.com> wrote:
>>> The issue is what if b is a property, returns a temporary object, and that
>>> temp's .c field is uselessly set to 3?
>>
>> So, the issue is that 'a.b()' returns a struct by value. Such return
>> values should always be considered rvalues. Furthermore,
>> 'rvalue.field' should also only yield an rvalue. Therefore, 'a.b.c =
>> 3' should be flagged by the compiler as being as nonsensical as "5 =
>> x".
>>
>> The compiler would flag this as an error, and the solution would of
>> course be to make a.b's return value by reference instead.
>
> 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?
> 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.
More information about the Digitalmars-d
mailing list