www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 'return this' allows binding rvalues to references

reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
foo() below takes by-ref. Normally, rvalues cannot be passed to it:

struct S
{
     ref S memFunc()
     {
         return this;
     }
}

void foo(ref S s)
{}

void main()
{
     // As expected, fails to compile:
     // foo(S());

     // No problem: Just call a function that returns ref... :)
     foo(S().memFunc());
}

Obviously, it is the same problem for rvalues returned from functions:

     S bar()
     {
         return S();
     }

     foo(bar().memFunc());    // <-- compiles

This may be a trap especially in opAssign() because it is recommended to 
return by-ref unless there is a reason not to. (I wonder whether this is 
a reason not to. :) )

struct S
{
     ref S opAssign(S rhs)
     {
         return this;
     }
}

void foo(ref S s)
{}

void main()
{
     // As expected, fails to compile:
     // foo(S());

     // No problem; just assign... :)
     foo(S() = S());
}

Allowing assignment to rvalue feels like a bug there but I don't think 
we can prevent the programmer from doing S().memFunc() as in the first case.

Ali

P.S. I should have checked before writing this post. The following bugs 
seem related:

   http://d.puremagic.com/issues/show_bug.cgi?id=1596

   http://d.puremagic.com/issues/show_bug.cgi?id=3008

No, I haven't read them yet.
Apr 08 2013
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 08 Apr 2013 13:58:17 -0400, Ali =C3=87ehreli <acehreli yahoo.com=
 wrote:
 foo() below takes by-ref. Normally, rvalues cannot be passed to it:

 struct S
 {
      ref S memFunc()
      {
          return this;
      }
 }

 void foo(ref S s)
 {}

 void main()
 {
      // As expected, fails to compile:
      // foo(S());

      // No problem: Just call a function that returns ref... :)
      foo(S().memFunc());
 }
It has been brought up before. Essentially, the compiler turns a blind eye when passing rvalues by = reference if binding to this. It's kind of unavoidable, to prevent it = would be a major pain point, since simple accessors should easily be abl= e = to be called on rvalues, and you can't remove the 'ref' of 'this'. I recall in the past, Andrei wishes to remove that possibility (maybe I'= m = wrong), but I think it would be too impractical. -Steve
Apr 08 2013
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/8/13 2:18 PM, Steven Schveighoffer wrote:
 Essentially, the compiler turns a blind eye when passing rvalues by
 reference if binding to this. It's kind of unavoidable, to prevent it
 would be a major pain point, since simple accessors should easily be
 able to be called on rvalues, and you can't remove the 'ref' of 'this'.

 I recall in the past, Andrei wishes to remove that possibility (maybe
 I'm wrong), but I think it would be too impractical.
Yes, that's a major hole. I'm mulling over a technique that fixes the general issue while not breaking much code. Andrei
Apr 08 2013