[Issue 5348] Variable Length Arrays

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Mar 28 15:55:20 PDT 2013


http://d.puremagic.com/issues/show_bug.cgi?id=5348



--- Comment #9 from bearophile_hugs at eml.cc 2013-03-28 15:55:17 PDT ---
Thank you for your comments.

> 1. VLAs are a failure in C99.

I agree, let's invent something better.

My ideas have changed, and now I think it's better to define DSSAA in library
code that is recognized and managed in a special way by the compiler, as here
for C++:

http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3532.html

Ada2012 has added stack-allocated collections. Rust allows any thing you want
to be allocated on the stack, if you want. They know that sometimes heap
allocations are bad for performance.

Dynamic-size stack-allocated arrays (abbreviated to DSSAA) will be a base to
create several other stack-allocated collections for D, as in Ada (and in
future Rust).


> 2. I'd prefer to deal with stack allocated arrays by optimization rather than
> new syntax & semantics, i.e.:
> 
>     int[] array = new int[5];
> 
> and determining that array[] can never leave its scope, and so can be allocated
> on the stack.

Your idea has problems:
1) Since some time Java has added escape analysis to stack-allocate some
objects and reduce a little the pressure on the GC. This feature is useful in
Java, but also it shows its limits, in many cases it fails, so it doesn't bring
a large improvement in Java.
2) I'd like DSSAA to be able to leave the scope (the simplest way to do this is
to "dup" on them, copying them on the heap. Below I show another way to do it).

A solution is to invent library-defined arrays that have a semantics different
from the regular dynamic arrays. See below.


> 3. Consider that static arrays are passed by value to functions, rather
> than by reference. VLAs for static arrays mess this up.

A solution is to add a special value array to Phobos, as in that n3532, and
then let the D compiler manage it in a special way, allocating it on the stack
where possible (if you use it inside a struct its storage goes on the heap,
like a dynamic array).


In the following case foo creates a DSSAA and returns it. A DSSAA keeps its
lenght beside the data, in the stack frame. At the return point inside bar()
bar allocates another DSSAA on the stack (increasing the size of the stack
frame of bar) and copies the received data:


import std.collections: ValArray;
ValArray!int foo(int n) {
    auto a = ValArray!int(n); // on the stack.
    return a;
}
void bar() {
    ValArray!int b = foo(5); // copied on the stack.
}


In this case foo() creates the DSSAA and calls bar with it. D just returns
pointer to the data on the stack frame plus length (so it's a kind of slice)
and then under the cover the data is also copied inside the stack frame of bar:

import std.collections: ValArray;
void foo(int n) {
    auto a = ValArray!int(n);
    bar(a);
}
void bar(ValArray!int b) {
}


Probably I have to open an enhancement request on this.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------


More information about the Digitalmars-d-bugs mailing list