継続マラソン - 継続の実装方法を考える2
shiroさんに頂いたコメントにあった問題点を自分なりに消化してみる。
デストラクタが呼ばれない場合
longjmp してしまうと auto変数のデストラクタが呼ばれない場合があるという話。
登場人物としては
- 僕の書いたクラス
- std::string/map/vector
が想定される。
どちらの場合も外の世界には関わっていないので、この処理系でデストラクタのやる仕事といえば、依存関係順にメモリを解放することがメイン。
ファイルを開いたりしているとファイルハンドルをデストラクタで close していたりとかあるけど今回はなさそう。
なのでメモリの解放はGC任せにすれば、これは大きな問題ではない。
デストラクタ呼ばれすぎ
call/cc で戻ってくると一度呼ばれたはずのデストラクタがまた呼ばれてしまう問題。
これは厄介。
僕の理解では2つ問題がある。
- auto変数として割り当てられた変数がコンストラクタ時にヒープから内部用にメモリを割り当て、デストラクタ時に解放みたいなクラスだと、一度目のデストラクト時に内部データが解放されてしまい。2度目に来たときに使えない。
- 複数回同一デストラクタが走り、その結果2重解放などが起こりうる。(C++的には delete は何回呼ばれても良いことになっているはずだけど)
STLのオプションで alloca を使うようにできないかなぁ(冗談)
shiroさんが指摘されている通り
std::系の便利なユーティリティとか気軽に使えなくなりますね。
ということになってしまいそうです。
自前の vector/string などは、恐らく内部データを new するのだけど、デストラクタでは何もしないという作りになって GC 前提のコレクションクラスになるでしょう。
じゃあどうするか
- 完全には理解できていない「CとSchemeのスタックをわける」という方法を調べる
- 難易度/今の実装にfitするか?などで方針を決める
- 最悪の場合 call/cc の実装は先伸ばし or 諦める(?)