Copy Constructor

Ali Çehreli acehreli at yahoo.com
Sun Jun 5 21:57:56 UTC 2022


On 6/5/22 11:43, Alain De Vos wrote:

 > Does Foo(3) lives on the stack or the heap ?

It depends.

 > there is a
 > conversion.

Suche conversions are called "construction" in D.

 > And what happes with
 > Foo[3] arr = [one, two, Foo(3)];

Foo[3] is a static array. Static arrays are value types. Their elements 
normally do not live on heap:

void foo() {
   Foo[3] arr;    // On the stack
}

However, if Foo[3] were a member of something else

class C {
   int i;
   Foo[3] arr;
}

and if an object of C is constructed on heap

   auto c = new C();

then the Foo[3] member will also live on the heap alongside 'i'.

It could be the opposite: If the class object were emplaced on stack, 
then every member would we on the stack.

As you see, "on the stack" really depends.

Let's assume that your example is inside a function, i.e. the array is 
on the stack:

void foo() {
   Foo[3] arr = [one, two, Foo(3)];
}

Now all members of 'arr' on the stack. As 'one' and 'two' are lvalues, 
they are copied to arr[0] and arr[1]. But as Foo(3) is an rvalue, as 
Paul Backus said in the other message, that element is moved to arr[2].

So there are two copies and one move.

 > Foo[]  arr=   [one, two, Foo(3)];

That one is different because Foo[] is a dynamic array that keeps its 
elements on the heap. That expression will allocate memory for at leasts 
3 elements and to the same: Two copies and one move.

 > and
 > Foo x=Foo(3).dup()

If there were a dup() member function of Foo:

struct Foo {
   Foo dup() {
     return Foo(this.payload);
   }
}

In that case, as the returned object is an rvalue, it would be moved to 
'x'. The returned object could be an lvalue:

struct Foo {
   Foo dup() {
     auto result = Foo(this.payload);
     // ...
     return result;
   }
}

In that case, the "named return value optimization" (NRVO) would be 
applied and the object would still be moved to 'x'.

Ali



More information about the Digitalmars-d-learn mailing list