Array literals are weird.

Dennis dkorpel at gmail.com
Sat May 1 15:29:06 UTC 2021


On Saturday, 1 May 2021 at 11:32:47 UTC, Blatnik wrote:
> Why? What's the reason for this design?

As mentioned before, static arrays have limited life time, so the 
compiler allocates arrays using the GC unless it is certain no 
references to it could escape.

> It also means that functions that take a slice parameter:
>
> ```D
> void foo(int[] bar);
> ```
>
> Can't be called naturally in @nogc or -betterC.
>
> ```D
> foo([1, 2, 3]) // Error: Array literal may cause GC allocation.
> ```
>

In this case, `foo` could e.g. store `bar` in a global variable 
causing memory corruption. It does work in `-betterC` if you add 
`scope` to the parameter, which means that `bar` is not allowed 
to leave the scope of the function:

```D
void foo(scope int[] bar) @nogc {}

extern(C) void main() @nogc {
     foo([1, 2, 3]);
}
```

> This decision to make array literals slice types by default 
> seems like a bad idea in all respects. It should be changed, 
> array literals (are) should be fixed size.

It would have to be done in a backwards compatible way, array 
literals are too common to introduce a breaking change.

> Any thoughts?

D's literals are full of somewhat ad-hoc rules that allow / 
disallow certain assignments that don't follow from their types.

- a string literal converts to a C-style string `const(char)*`, 
but a `string` does not convert to a `const(char)*`
- an integer literal converts to a `short` if it fits, though 
`int` does not convert to `short` (this is called "value range 
propagation")
- an integer array literal `[1, 2, 3]` converts to a `float[]`, 
though an `int[]` does not convert to `float[]`
- conversely, an invalid code point `0x110000` can *not* be 
assigned to a `dchar`, even though `int` converts to `dchar`

The fact that static arrays are initialized using dynamic array 
literals is another instance of this. I'd personally be in favor 
of dedicated static array literals, but I'm afraid most people 
are satisfied with `import std.array: staticArray;`.


More information about the Digitalmars-d mailing list