On Wednesday, 17 March 2021 at 14:30:26 UTC, Guillaume Piolat
wrote:
On Wednesday, 17 March 2021 at 10:54:10 UTC, jmh530 wrote:
This is one of those things that is not explained well enough.
Yes.
I made this article to clear up that point:
https://p0nce.github.io/d-idioms/#Slices-.capacity,-the-mysterious-property
"That a slice own or not its memory is purely derived from the
pointed area."
could perhaps better be said
"A slice is managed by the GC when the memory it points to is
in GC memory"?
I probably skimmed over the link when I originally read it
without really understanding it. I'm able to understand it now.
I think the underlying issue that needs to get explained better
is that when you do
int[] x = [1, 2, 3];
the result is always a GC-allocated dynamic array. However, z
below
int[3] y = [1, 2, 3];
int[] z = y[];
does not touch the GC at all. For a long time, I operated under
the assumption that dynamic arrays and slices are the same thing
and that dynamic arrays are always GC-allocated. z is obviously a
slice of y, but it is also a dynamic array in the sense that you
can append to it and get an array with one more member than y
(except in @nogc code). However, when appending to z, it seems
that what's really happening is that the GC is allocating a new
part of memory, copying over the original value of y and then
copying in the new value. So it really becomes a new kind of
thing (even if the type is unchanged).
One takeaway is there is no issue with a function like below
@nogc void foo(T)(T[] x) {}
so long as you don't actually need the GC within the function. A
static array can be passed in just using a slice.