www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opAssign and references

reply Nicolas Silva <nical.silva gmail.com> writes:
Hi,

I'm playing with variants and I noticed that opAssign is not invoked
when an assignation is done on a reference.

here is the test case:

import std.variant;

struct Foo
{
    Variant a;
    Variant b;
    ref Variant refA()
    {
        return a;
    }
}

void main()
{
    Foo f1;
    f1.a = 42; // ok
    f1.b = 23; // ok

    f1.refA() = 24; // Error: cannot implicitly convert expression
(24) of type int to VariantN!(maxSize)
    f1.refA().opAssign( 24 ); // ok, but not very nice...

    // slightly OT but
    Foo f2 = { a: 10 }; // Error: cannot implicitly convert expression
(10) of type int to VariantN!(maxSize)
}


Is it normal? Am I missing something?
I took Variant as an example because it does use opAssign but one
could create a struct defining opAssign with the same results.

More generally, I feel like I don't really understand the semantic of
opAssign (or maybe references). I'd intuitively expect it to be
invoked when the "=" operator is used on a reference and I'd also
expect it to be invoked in struct initializers (though there might be
something  about compiletime / runtime stories in this particular
case, yet i think one would expect it to just work).

D aims at being simple and intuitive, and in this case it looks not so
intuitive to me.

Best regards,

Nicolas Silva
Jan 31 2012
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/31/2012 03:03 PM, Nicolas Silva wrote:
 Hi,

 I'm playing with variants and I noticed that opAssign is not invoked
 when an assignation is done on a reference.

 here is the test case:

 import std.variant;

 struct Foo
 {
      Variant a;
      Variant b;
      ref Variant refA()
      {
          return a;
      }
 }

 void main()
 {
      Foo f1;
      f1.a = 42; // ok
      f1.b = 23; // ok

      f1.refA() = 24; // Error: cannot implicitly convert expression
 (24) of type int to VariantN!(maxSize)

Works for me. Which version of the compiler are you using?
      f1.refA().opAssign( 24 ); // ok, but not very nice...

      // slightly OT but
      Foo f2 = { a: 10 }; // Error: cannot implicitly convert expression
 (10) of type int to VariantN!(maxSize)

This is http://d.puremagic.com/issues/show_bug.cgi?id=7019
 }


 Is it normal? Am I missing something?
 I took Variant as an example because it does use opAssign but one
 could create a struct defining opAssign with the same results.

 More generally, I feel like I don't really understand the semantic of
 opAssign (or maybe references). I'd intuitively expect it to be
 invoked when the "=" operator is used on a reference and I'd also
 expect it to be invoked in struct initializers (though there might be
 something  about compiletime / runtime stories in this particular
 case, yet i think one would expect it to just work).

 D aims at being simple and intuitive, and in this case it looks not so
 intuitive to me.

If something is not as simple and intuitive as it ought to be, there might be a compiler bug.
 Best regards,

 Nicolas Silva

Jan 31 2012
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/31/2012 06:15 PM, Nicolas Silva wrote:
 Hi,

 Works for me. Which version of the compiler are you using?

Sorry, i forgot to mention: i'm using dmd 2.057 on ubuntu 32bit.

I am using DMD 2.057 on Ubuntu 64bit. Are you sure that it does not work? Can anyone reproduce the error? import std.variant; struct Foo { Variant a; ref Variant refA(){ return a; } } void main(){ Foo f1; f1.refA() = 24; }
Jan 31 2012
parent sclytrack <sclytrack hotmail.com> writes:
On 02/01/2012 07:15 AM, Simen Kjærås wrote:
 On Wed, 01 Feb 2012 01:14:38 +0100, Nicolas Silva
 <nical.silva gmail.com> wrote:

 Oh, my bad, sorry, when I tried the code i showed in the other mail, I
 had forgotten the parenthesis on the call to refA() (like if it was an
 attribute).

 Once fixed it works for me.

 f1.refA() = 24; //ok
 f1.refA = 24; //not ok, my mistake

Still, this should work, and it does under DMD trunk. Can confirm that this is a bug under 2.057 and earlier (at least 2.056 :p).

I can confirm that this doesn't work under 2.057 but works on the newer version I checked out a couple of days ago. Both -m32 and -m64. Of course it doesn't work with the -property flag which requires () for methods. Short version: Don't file a bug.
Feb 01 2012
prev sibling next sibling parent Nicolas Silva <nical.silva gmail.com> writes:
Hi,

 Works for me. Which version of the compiler are you using?

Sorry, i forgot to mention: i'm using dmd 2.057 on ubuntu 32bit. On Tue, Jan 31, 2012 at 5:31 PM, Timon Gehr <timon.gehr gmx.ch> wrote:
 On 01/31/2012 03:03 PM, Nicolas Silva wrote:
 Hi,

 I'm playing with variants and I noticed that opAssign is not invoked
 when an assignation is done on a reference.

 here is the test case:

 import std.variant;

 struct Foo
 {
 =A0 =A0 Variant a;
 =A0 =A0 Variant b;
 =A0 =A0 ref Variant refA()
 =A0 =A0 {
 =A0 =A0 =A0 =A0 return a;
 =A0 =A0 }
 }

 void main()
 {
 =A0 =A0 Foo f1;
 =A0 =A0 f1.a =3D 42; // ok
 =A0 =A0 f1.b =3D 23; // ok

 =A0 =A0 f1.refA() =3D 24; // Error: cannot implicitly convert expression
 (24) of type int to VariantN!(maxSize)

Works for me. Which version of the compiler are you using?
 =A0 =A0 f1.refA().opAssign( 24 ); // ok, but not very nice...

 =A0 =A0 // slightly OT but
 =A0 =A0 Foo f2 =3D { a: 10 }; // Error: cannot implicitly convert expres=


 (10) of type int to VariantN!(maxSize)

This is http://d.puremagic.com/issues/show_bug.cgi?id=3D7019
 }


 Is it normal? Am I missing something?
 I took Variant as an example because it does use opAssign but one
 could create a struct defining opAssign with the same results.

 More generally, I feel like I don't really understand the semantic of
 opAssign (or maybe references). I'd intuitively expect it to be
 invoked when the "=3D" operator is used on a reference and I'd also
 expect it to be invoked in struct initializers (though there might be
 something =A0about compiletime / runtime stories in this particular
 case, yet i think one would expect it to just work).

 D aims at being simple and intuitive, and in this case it looks not so
 intuitive to me.

If something is not as simple and intuitive as it ought to be, there migh=

 be a compiler bug.

 Best regards,

 Nicolas Silva


Jan 31 2012
prev sibling next sibling parent Trass3r <un known.com> writes:
 I am using DMD 2.057 on Ubuntu 64bit. Are you sure that it does not  
 work? Can anyone reproduce the error?

 import std.variant;
 struct Foo {
      Variant a;
      ref Variant refA(){
          return a;
      }
 }
 void main(){
      Foo f1;
      f1.refA() = 24;
 }

Compiles fine on Ubuntu x64 with git dmd and -m(32|64)
Jan 31 2012
prev sibling next sibling parent Nicolas Silva <nical.silva gmail.com> writes:
Oh, my bad, sorry, when I tried the code i showed in the other mail, I
had forgotten the parenthesis on the call to refA() (like if it was an
attribute).

Once fixed it works for me.

f1.refA() =3D 24; //ok
f1.refA =3D 24; //not ok, my mistake


On Tue, Jan 31, 2012 at 11:43 PM, Trass3r <un known.com> wrote:
 I am using DMD 2.057 on Ubuntu 64bit. Are you sure that it does not work=


 Can anyone reproduce the error?

 import std.variant;
 struct Foo {
 =A0 =A0 Variant a;
 =A0 =A0 ref Variant refA(){
 =A0 =A0 =A0 =A0 return a;
 =A0 =A0 }
 }
 void main(){
 =A0 =A0 Foo f1;
 =A0 =A0 f1.refA() =3D 24;
 }

Compiles fine on Ubuntu x64 with git dmd and -m(32|64)

Jan 31 2012
prev sibling parent =?utf-8?Q?Simen_Kj=C3=A6r=C3=A5s?= <simen.kjaras gmail.com> writes:
On Wed, 01 Feb 2012 01:14:38 +0100, Nicolas Silva <nical.silva gmail.com>  
wrote:

 Oh, my bad, sorry, when I tried the code i showed in the other mail, I
 had forgotten the parenthesis on the call to refA() (like if it was an
 attribute).

 Once fixed it works for me.

 f1.refA() = 24; //ok
 f1.refA = 24; //not ok, my mistake

Still, this should work, and it does under DMD trunk. Can confirm that this is a bug under 2.057 and earlier (at least 2.056 :p).
Jan 31 2012