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









psycha0s <box mail.com> 