DIP 1025--Dynamic Arrays Only Shrink, Never Grow--Community Review Round 1

Jonathan M Davis newsgroup.d at jmdavisprog.com
Mon Nov 11 11:51:09 UTC 2019

On Monday, November 11, 2019 4:33:00 AM MST Dukc via Digitalmars-d wrote:
> I'll repeat what I said in the draft review, because I don't know
> whether my feedback wasn't noticed. In addition, I'll be more
> explicit.
> In no practical way we can implement this. The breakage would
> most likely dwarf breaking autodecoding.
> However, the above only applies to breaking appending to slices
> in general. I agree that if the slice is not either:
> 1. GC-allocated
> 2. referring to a static array.
> 3. referring to an initialization value of an array of `static`
> storage class
> ...then the chances of somebody appending to it are low enough
> that breaking might be viable. Even then, somebody might append
> to a mallocated slice by GC if there is another reference to the
> original slice lying around, but for me that sounds rare enough
> that finding memory leaks could justify the breakage.
> I see two alternatives. We can simply discourage growing slices
> with the garbage collector. A transition switch would be
> introduced, but no removing `~` or `slice.length += 2` totally,
> or at least not for many years. We also could introduce a new
> appending operator, say >< (along with ><=), which behaves just
> like ~ but refuses to work with slices, and encourage to use that
> istead of the present append operator.
> The other alternative is that slice growing by GC would check
> where the array is referring to. First, if it refers to null, the
> static memory area or the stack, check passed. Second, if it
> refers to anything the GC controls, check passed. Otherwise, it's
> assumed it's pointing to mallocated memory, or just corrupt -
> program terminated with an unrecoverable error. For @system code,
> the compiler could forgo these checks with the same rules as
> array bounds checks can be forgoed. Growing a slice of mallocated
> memory where the check is omitted would be undefined behaviour.

IMHO, the ability to append to a dynamic array without caring whether it's
backed by GC-allocated memory, malloc-ed memory, stack allocated memory, or
whatever is a huge benefit. Right now, you can pass a dynamic array that
isn't backed by the GC to a function, and it all just works even if the
function needs to do a reallocation to make the array large enough. Doing so
is not necessarily a bug and allows you to use non-GC allocated memory where
appropriate while still being able to grow the array, and it does so without
the code having to care about what kind of memory is currently backing the
dynamic array. And if the code _does_ care for some reason, the array's
capacity property will tell you whether the array can be grown in-place, and
multiple functions in core.memory can be used to determine whether the
dynamic array is a slice of GC-allocated memory.

- Jonathan M Davis

More information about the Digitalmars-d mailing list