Editions Ideas

Quirin Schroll qs.il.paperinik at gmail.com
Fri Jan 16 16:03:40 UTC 2026


On Sunday, 14 December 2025 at 20:23:51 UTC, Walter Bright wrote:
> On 12/14/2025 3:44 AM, Paul Backus wrote:
>> We can (and should) improve memory safety by closing holes in 
>> @safe. For example, instead of using -preview=dip1000 we can 
>> simply forbid @safe code from taking the address of a 
>> stack-allocated variable (passing by `ref` is fine though).
>
> Then you cannot have arrays on the stack, which are a highly 
> useful construct (I use them all the time).

As of now, in D, you can only have static arrays on the stack. 
When you do
```d
scope int[] xs = [1,2,3];
```
What you get is:
```d
int[3] __xs = [1,2,3];
int[] xs = __xs[];
```
That’s not bad, but it only works for plain literals. This fails:
```d
scope int[] xs = condition() ? [1,2] : [1,2,3];
```

Unfortunately, you can’t have actual dynamic arrays:
```d
void f(size_t n) @nogc @safe
{
     scope int[] xs = new int[](n); // error: GC-alloc in @nogc
}
```
If D had this, `@nogc` would gain a lot.


The only thing I’m unsure about is what to do if `n` is large. It 
can blow your stack. Can the compiler check beforehand if it will 
and throw an `Error`?

C# has `stackalloc` for that.

What D could have is a `@stackalloc` attribute for local 
variables (not function parameters):
```d
void f(size_t n) @safe
{
     scope int[] xs = new int[](n);
     @stackalloc int[] ys = new int[](n);
}
```
1. `xs` will be allocated on the stack if `n` is small 
(implementation-defined), otherwise heap allocated. The idea 
being, if `n` is big, heap allocation isn’t that big of a 
performance hit anyways, but what you get is that small buffers 
are optimized to go on the stack.
2. `ys` is guaranteed to be allocated on the stack, you trade 
“pessimization, but it just works” for “guaranteed stack alloc, 
but throws Error if too big”.

Generally, `@stackalloc` implies `scope`. In a `@nogc`-annotated 
function, `new T[](…)` requires assignment to a `@stackalloc` 
local variable.

The only open question: Templates that infer `@nogc`. I’d say, if 
they use
```d
scope int[] xs = new int[](n);
```
they’re possibly allocating unless VRP can prove `n` is small 
enough.

For the time being,
```d
scope int[] xs = condition() ? [4,5] : [1,2,3];
```
can be implemented as:
```d
static int[2] l = [4,5];
static int[3] r = [1,2,3];
int[3] _xs = void;
scope int[] xs = cond()
     ? (_xs[0..2] = l[])
     : (_xs[0..3] = r[]);
```


More information about the Digitalmars-d mailing list