View mode: basic / threaded / horizontal-split · Log in · Help
January 31, 2012
opAssign and references
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
January 31, 2012
Re: opAssign and references
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
January 31, 2012
Re: opAssign and references
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
>> {
>>     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
>
>
January 31, 2012
Re: opAssign and references
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;
}
January 31, 2012
Re: opAssign and references
> 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)
February 01, 2012
Re: opAssign and references
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


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 {
>>     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)
February 01, 2012
Re: opAssign and references
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).
February 01, 2012
Re: opAssign and references
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.
Top | Discussion index | About this forum | D home