【D言語】クラスのインスタンスをスタック上に構築する

サイズの小さいクラスを関数内でサクッと使い捨てしたいことが稀にある。
そういうインスタンスは、ヒープ上ではなくスタック上に確保したくなるのが人情というもの。
で、D言語ではそれができるのだが、個人的に「あれ?やり方とか色々どうだっけ?」となりがちなので備忘録としてメモ。
dmd 2.098.0 で動作確認。
結論
例えば Color
というクラスがあったとして、以下の一文でインスタンスをスタック上に構築できる。
scope c = new Color();
scope
で変数が修飾されているのがポイントだ。
変数定義を単に auto c
とか Color c
とかにしてしまうと、ヒープ上に確保されGCの管理下に入る。
その他補足
補足1
クラスのコンストラクタとデストラクタが @nogc
なら、new
しているにもかかわらず関数を @nogc
で修飾できるらしい。すごい。
void func() @nogc // <- 関数を @nogc にできる! { scope c = new Color(); // <- "new" してるのに! やったね! }
当然、デストラクタはスコープを抜ける際に 即時 呼び出される。
補足2
スタックへの参照なので、外部に漏れるとマズい。
しかし、関数が @safe
で修飾されていれば、参照を逃がそうとするコードはすべてコンパイルエラーになるので安心だ。
Color g_Color; Color func() @nogc @safe // <- @safeコード下なので… { scope c = new Color(); // ↓こいつらはコンパイルがそもそも通りません。助かったぜ。 version (none) { g_Color = c; return c; } }
未検証のこと
@nogc
関数内で、でかいインスタンスをスタックに作ろうとするとどうなるんかね?
C# の stackalloc
みたいに StackOverflow
的なエラーになるなら、閾値はどんなもんなんだろう?
プリミティブ型のメンバを2,3持つ程度のクラスなら、まあまず大丈夫だろうから、個人的には問題にはならなさそうではあるが…
こんど時間に余裕があったら調べてみよう。
-preview=in
の参照渡し境界サイズみたいに、環境依存とかだったら怖いからね…