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