Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
July 09, 2020 Unexpected copy constructor behavior | ||||
---|---|---|---|---|
| ||||
I was learning copy constructors and got a really weird result. It looks like a copy constructor and a destuctor of two unknown objects are called. Could somebody please explain it to me? >import std.stdio; > >struct Foo { > int value; > > this(int n) > { > value = n; > writeln("constuctor ", &this); > } > > ~this() > { > writeln("destuctor ", &this); > } > > this(ref return scope Foo other) > { > value = other.value; > writeln("copy constuctor ", &this); > } >} > >void main() >{ > writeln("begin"); > auto foo1 = Foo(1); > auto foo2 = foo1; > writeln("---"); > foo2 = foo1; > writeln("==="); > writeln("end"); >} The output: >begin >constuctor A3D3EFF860 >copy constuctor A3D3EFF864 >--- >copy constuctor A3D3EFF880 // <-- >destuctor A3D3EFF808 // <-- >=== >end >destuctor A3D3EFF864 >destuctor A3D3EFF860 |
July 09, 2020 Re: Unexpected copy constructor behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to psycha0s | I just didn't expect that the address of a "this" reference may change. |
July 09, 2020 Re: Unexpected copy constructor behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to psycha0s | On 7/9/20 6:08 PM, psycha0s wrote:
> import std.stdio;
>
> struct Foo {
> int value;
>
> this(int n)
> {
> value = n;
> writeln("constuctor ", &this);
> }
>
> ~this()
> {
> writeln("destuctor ", &this);
> }
>
> this(ref return scope Foo other)
> {
> value = other.value;
> writeln("copy constuctor ", &this);
> }
> }
>
> void main()
> {
> writeln("begin");
> auto foo1 = Foo(1);
> auto foo2 = foo1;
> writeln("---");
> foo2 = foo1;
> writeln("===");
> writeln("end");
> }
Looking at the generated AST, it's because the compiler is adding an auto-generated opAssign, which accepts a Foo by value. It is that object that is being created and destroyed. Your objects aren't moving.
Here is what AST looks like for main:
void main()
{
writeln("begin");
Foo foo1 = foo1 = 0 , foo1.this(1);
try
{
Foo foo2 = foo2 = 0 , foo2.this(foo1);
try
{
writeln("---");
foo2.opAssign(((Foo __copytmp434 = __copytmp434 = 0 , __copytmp434.this(foo1);) , __copytmp434));
writeln("===");
writeln("end");
}
finally
foo2.~this();
}
finally
foo1.~this();
return 0;
}
-Steve
|
July 10, 2020 Re: Unexpected copy constructor behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 9 July 2020 at 22:18:59 UTC, Steven Schveighoffer wrote:
> Looking at the generated AST, it's because the compiler is adding an auto-generated opAssign, which accepts a Foo by value. It is that object that is being created and destroyed.
Is there a reason the autogenerated opAssign accepts its argument by value? Honestly, it looks like a premature pessimisation to me.
|
July 10, 2020 Re: Unexpected copy constructor behavior | ||||
---|---|---|---|---|
| ||||
Posted in reply to psycha0s | On 7/10/20 3:31 AM, psycha0s wrote:
> On Thursday, 9 July 2020 at 22:18:59 UTC, Steven Schveighoffer wrote:
>> Looking at the generated AST, it's because the compiler is adding an auto-generated opAssign, which accepts a Foo by value. It is that object that is being created and destroyed.
>
> Is there a reason the autogenerated opAssign accepts its argument by value? Honestly, it looks like a premature pessimisation to me.
If it accepts the value by ref, then it will not bind to rvalues. Accepting by value accepts anything.
-Steve
|
Copyright © 1999-2021 by the D Language Foundation