digitalmars.D.learn - Unexpected copy constructor behavior
- psycha0s (4/42) Jul 09 2020 I was learning copy constructors and got a really weird result.
- psycha0s (2/2) Jul 09 2020 I just didn't expect that the address of a "this" reference may
- Steven Schveighoffer (28/61) Jul 09 2020 Looking at the generated AST, it's because the compiler is adding an
- psycha0s (4/7) Jul 10 2020 Is there a reason the autogenerated opAssign accepts its argument
- Steven Schveighoffer (4/11) Jul 10 2020 If it accepts the value by ref, then it will not bind to rvalues.
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
Jul 09 2020
I just didn't expect that the address of a "this" reference may change.
Jul 09 2020
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
Jul 09 2020
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.
Jul 10 2020
On 7/10/20 3:31 AM, psycha0s wrote:On Thursday, 9 July 2020 at 22:18:59 UTC, Steven Schveighoffer wrote:If it accepts the value by ref, then it will not bind to rvalues. Accepting by value accepts anything. -SteveLooking 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.
Jul 10 2020