Как инициализировать статические массивы в D без выделения GC? - PullRequest
10 голосов
/ 19 июля 2011

В D все литералы массива являются динамическими массивами и поэтому выделяются GC.

Даже в этом простом примере:

int[3] a = [10, 20, 30];

Массив выделяется в куче, а затем копируется в a.

Как вы должны инициализировать статический массив без выделения кучи?

Вы можете сделать это вручную:

int[3] a = void;
a[0] = 10;
a[1] = 20;
a[2] = 30;

Но в лучшем случае это утомительно.

Есть ли лучший способ?

Ответы [ 5 ]

9 голосов
/ 19 июля 2011
static const int[3] a = [10, 20, 30];

Это поместит постоянную копию в сегмент данных. Вы можете создать копию в стеке (без выделения кучи) с помощью простого назначения (auto copy = a;).

3 голосов
/ 19 июля 2011

I думаю, , если вы могли бы объявить литерал как immutable глобально, а затем использовать его как инициализатор, выделения кучи нет - но я могу ошибаться, я не уверен.*

1 голос
/ 14 мая 2017

2017 ОБНОВЛЕНИЕ: В любой недавней версии DMD использование инициализатора массива для статического массива больше не выделяется, даже если статический массив является локальной переменной (т. Е. Размещается в стеке).

Вы можете проверитьСделайте это самостоятельно, создав функцию, в которой инициализируется статический массив, а затем пометив функцию как @nogc и наблюдая, компилируется ли она.Пример:

import std.random;
import std.stdio;
int[4] testfunc(int num) @nogc
{
    return [0, 1, num, 3];
}

int main()
{
    int[4] arr = testfunc(uniform(0, 15));
    writeln(arr);
    return 0;
}

Поскольку testfunc () компилируется, несмотря на то, что он @nogc, мы знаем, что инициализатор массива не выделяет.

1 голос
/ 14 сентября 2011

Это просто ошибка компилятора. Я видел это в багзилле DMD. Это должно быть исправлено (DMD 2.055).

1 голос
/ 19 июля 2011

Я думаю, что вы можете немного ошибаться: в http://www.digitalmars.com/d/2.0/arrays.html#static-init-static

Статическая инициализация статических массивов

Статические инициализации предоставляются списком значений элементов массива, заключенных в [].Значениям могут предшествовать индекс и a:.Если индекс не указан, ему присваивается предыдущий индекс плюс 1 или 0, если это первое значение.

-snip-

Эти массивы являются статическими, когда они появляются в глобальномобъем.В противном случае они должны быть помечены как const или статические классы хранения, чтобы сделать их статическими массивами.

с примером кода

int[3] a = [ 1:2, 3 ]; // a[0] = 0, a[1] = 2, a[2] = 3

, что означает, что const a[3] = [10, 20, 30]; не будет /не должно ничего выделять в куче

...