RFC: scope and borrowing
bearophile via Digitalmars-d
digitalmars-d at puremagic.com
Wed Aug 27 04:47:20 PDT 2014
Marco Leise:
> The amount of possible use-cases you listed for this extension
> is staggering.
With scope management in code like this:
import std.stdio, std.algorithm;
int foo(in int[] a) {
return sum([0, 1] ~ a[1 .. $ - 2] ~ 0 ~
[a[$ - 1] + 1, a[$ - 1] + 2]);
}
void main() {
int[5] b = [10, 20, 30, 40, 50];
b.foo.writeln;
}
The compiler in theory could lower the code to something like
this, removing all heap allocations for the array literals and
the concatenations, allowing 'foo' to be annotated with @nogc (I
don't know if Rust is able to do this, I presume it can):
import std.stdio, std.algorithm, core.stdc.stdlib;
T foo(T)(in T[] a) @nogc {
immutable size_t L = 2 + a.length - 3 + 1 + 2;
auto ptr = alloca(T.sizeof * L);
if (ptr == null)
exit(1); // Or throw a stack overflow error.
T[] b = (cast(T*)ptr)[0 .. L];
b[0] = 0;
b[1] = 1;
b[2 .. $ - 3] = a[1 .. $ - 2];
b[$ - 3] = 0;
b[$ - 2] = a[$ - 1] + 1;
b[$ - 1] = a[$ - 1] + 2;
return sum(b);
}
void main() {
int[5] c = [10, 20, 30, 40, 50];
c.foo.writeln;
}
But in some cases you don't want those arrays to be allocated on
the stack because you know they are very large. So the [...]s
array literal syntax becomes useful again:
import std.stdio, std.algorithm;
int foo(const scope int[] a) {
return sum([0, 1]s ~ a[1 .. $ - 2] ~ 0 ~
[a[$ - 1] + 1, a[$ - 1] + 2]s);
}
But this is still not enough, because even if those parts are all
safely stack-allocated, the result of the concatenation is still
not stack-allocated.
This could be enough:
import std.stdio, std.algorithm;
int foo(const scope int[] a) @nogc {
auto[$] a2 = [0, 1]s ~ a[1 .. $ - 2] ~ 0 ~
[a[$ - 1] + 1, a[$ - 1] + 2]s;
return sum(a2[]);
}
Bye,
bearophile
More information about the Digitalmars-d
mailing list