Dでは、すべての配列リテラルは動的配列であるため、GCによって割り当てられます。
この単純な例でも:
int[3] a = [10, 20, 30];
配列はヒープに割り当てられてから、にコピーされa
ます。
ヒープを割り当てずに静的配列を初期化するにはどうすればよいですか?
手動で行うことができます:
int[3] a = void;
a[0] = 10;
a[1] = 20;
a[2] = 30;
しかし、これはせいぜい退屈です。
もっと良い方法はありますか?
Dでは、すべての配列リテラルは動的配列であるため、GCによって割り当てられます。
この単純な例でも:
int[3] a = [10, 20, 30];
配列はヒープに割り当てられてから、にコピーされa
ます。
ヒープを割り当てずに静的配列を初期化するにはどうすればよいですか?
手動で行うことができます:
int[3] a = void;
a[0] = 10;
a[1] = 20;
a[2] = 30;
しかし、これはせいぜい退屈です。
もっと良い方法はありますか?
static const int[3] a = [10, 20, 30];
これにより、データセグメントに一定のコピーが配置されます。単純な割り当て()を使用して、スタック上にコピーを作成できます(ヒープ割り当ては含まれませんauto copy = a;
)。
リテラルをグローバルとして宣言し、それを初期化子として使用できれば、ヒープの割り当てはないと思いimmutable
ますが、間違っている可能性があります。よくわかりません。
これは単なるコンパイラのバグです。DMDのbugzillaで見ました。これで修正されるはずです(DMD2.055)。
私はあなたが少し間違っているかもしれないと思います:http ://www.digitalmars.com/d/2.0/arrays.html#static-init-staticで
静的配列の静的初期化
静的な初期化は、[]で囲まれた配列要素値のリストによって提供されます。オプションで、値の前にインデックスと:を付けることができます。インデックスが指定されていない場合は、前のインデックスに1を加えた値に設定されます。最初の値の場合は、0に設定されます。
-をちょきちょきと切る-
これらの配列は、グローバルスコープに表示される場合は静的です。それ以外の場合は、静的配列にするためにconstまたは静的ストレージクラスでマークする必要があります。
コード例付き
int[3] a = [ 1:2, 3 ]; // a[0] = 0, a[1] = 2, a[2] = 3
つまりconst a[3] = [10, 20, 30];
、ヒープに何も割り当てない/割り当てるべきではないということです
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であるにもかかわらずコンパイルされるため、配列初期化子が割り当てないことがわかります。