Ouch: return values as lvalue

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Tue Jan 30 23:10:48 PST 2007


Lionello Lunesu wrote:
> "Andrei Alexandrescu (See Website For Email)" 
> <SeeWebsiteForEmail at erdani.org> wrote in message 
> news:45BF7C8B.3080506 at erdani.org...
>> Lionello Lunesu wrote:
>>> Consider this home-made const:
>>>
>>> struct Task {
>>>   char[] ID;
>>> }
>>> private Task _CurrentTask; //mutable
>>> public Task CurrentTask() { return _CurrentTask; } //const
>>>
>>> public void StopTask() {
>>>   CurrentTask.ID = null;
>>> }
>>>
>>> Notice the bug? That last line should read "_CurrentTask.ID = null;"
>>>
>>> Isn't there something the compiler can do to help me catch these bugs?
>> const will take care of it. The code above fetches a member of an rvalue, 
>> which is an lvalue.
> 
> I've been thinking about this some more. Why exactly is a member of an 
> rvalue, an lvalue?
> 
> struct S { int i; }
> //foo returns a struct, which is placed on stack/register, somewhere anyway
> S foo();
> foo() = myS; // not allowed
> foo().i = 2; // suddenly allowed! Why?
> 
> // func returns an int, which is also placed somewhere,
> // physically, stack/register doesn't matter
> int func();
> func() = 2;   // I can't write this... why?
> 
> What exactly is the difference between setting the whole thing, or only one 
> of its members? In the case of S above, there's no real difference, yet they 
> behave differently?

I think that's a good point, but I wouldn't put a lot of faith in it. An 
rvalue accepts member function calls, which in turn can return things 
like pointers (now) or lvalues (later).

Probably calling certain members should be disallowed on rvalue objects, 
but right now D does not give such flexibility.


Andrei



More information about the Digitalmars-d mailing list