Unwind-safe scope(failure)

D 言語の scope(failure) を極大級 C++ 闇魔法を総投入してでもエミュレートしたいが stack unwind のときにどうしよう問題.
8
前へ 1 2 ・・ 5 次へ
Akso de la Malbono @Cryolite

@decimalbloat std::uncaught_exception を使って判定するのはまずいというところまでが昨日の結論だったので, scope(exit) のみを提供して(全部の副作用が成功したら)それらを無効化する設計にすべきだと思いました.

2012-03-19 02:03:26
Akso de la Malbono @Cryolite

@decimalbloat 元々(10年くらい前?), C++ における scope guard のエミュレーションはユーザに scope guard の名前を付けさせて,ユーザが個々の scope guard を無効化できるインタフェイスが付いてました.

2012-03-19 02:05:08
Akso de la Malbono @Cryolite

@decimalbloat なので,元々の scope guard オブジェクトは個々に bool の flag を持っていて,それによって destructor で rollback を起動するかどうかを実行時に分岐してました.

2012-03-19 02:06:58
Akso de la Malbono @Cryolite

@decimalbloat ただ, SG のほとんどの利用パタンでは個々の SG の有効・無効を制御する必要はなくて「現在のスコープで宣言したものを全部無効化する」か「lexical に見えているものを全部無効化する」かのどちらかで十分だと思います.

2012-03-19 02:10:00
Akso de la Malbono @Cryolite

@decimalbloat さっきうpしたものは「あるスコープで宣言された SG だけを一斉に無効化する」というものです.内側の scope で return するケースもあるので「lexical に見えている SG を全部無効化」も追加する必要があると思います.

2012-03-19 02:11:59
Akso de la Malbono @Cryolite

@decimalbloat で,元々の設計に立ち戻って,全部の SG の発動フラグをスレッドローカルな flag 1つにまとめて,その flag を触るだけで複数の SG の発動を一斉に制御すればどうかと.スレッドローカルにしてあるのは race-free にするためです.

2012-03-19 02:15:49
Akso de la Malbono @Cryolite

@decimalbloat あと「そのブロックスコープで宣言されたものだけ無効化の対象とする」を実現するために,あるブロックスコープで初めて宣言されたものだけにマーキングする技法を使っています.基本的なアイデアを説明すると http://t.co/aIxuZgNS

2012-03-19 02:24:15
でちまるさん(実際かわいい) @decimalbloat

@Cryolite とても長い説明ありがとうございました.ところでスコープ単位かもしくはlexicalに見える範囲を単位として制御するのであれば,フラグは別にグローバル変数じゃなくてローカル変数でもいいと思うのですがどうでしょう?

2012-03-19 02:34:39
でちまるさん(実際かわいい) @decimalbloat

@Cryolite フラグとなるローカル変数はスコープまたはlexicalに見える範囲において一度だけ宣言します(もちろんユーザにそのフラグを明示的に書かせるわけではなく,SGの構文に含めます)

2012-03-19 02:36:27
Akso de la Malbono @Cryolite

@decimalbloat はい.もちろんそうなんですが,ユーザにそのローカル変数を一切見せることなく,しかも無効化のときに触る,というのは1日瞑想しましたが私の非力な闇魔力では詠唱できませんでした.すいません.

2012-03-19 02:38:28
でちまるさん(実際かわいい) @decimalbloat

@Cryolite 今のBoost.ScopeGuardはlexicalに見える範囲において一度だけ変数宣言となるような技巧が使われているので,それ参考にしたらいけそうだと思ったのです.

2012-03-19 02:41:06
Akso de la Malbono @Cryolite

@decimalbloat 同じ preprocess token を使いながら,その内部にオブジェクトの宣言・定義をあるスコープ内できっかり一度だけ行う闇魔法を織り込む,ということになると思いますが私には詠唱しきれませんでした.(関数の宣言ならもちろん複数回できますが)

2012-03-19 02:41:28
でちまるさん(実際かわいい) @decimalbloat

あれは確か私の日記にまとめられていたはず

2012-03-19 02:41:35
Akso de la Malbono @Cryolite

@decimalbloat あ,はい.さっき思い出して後で見ようと思ってました.

2012-03-19 02:42:36
Akso de la Malbono @Cryolite

@decimalbloat あと関係ないですが,あるブロックスコープ内で異なる番号を連番で振っていく闇魔法があるので使える場面があったら使ってやってください. http://t.co/g7mh37iv SG を部分的に無効化するために使えるかと思ってたんですが要らなさそうなので.

2012-03-19 02:45:05
Akso de la Malbono @Cryolite

@decimalbloat あれ? 私見せたことありましたっけ?

2012-03-19 02:50:10
でちまるさん(実際かわいい) @decimalbloat

@Cryolite 大分前の日記にFOREACH書いてましたよね.そこでも似たようなことやってましたよ.

2012-03-19 02:53:34
でちまるさん(実際かわいい) @decimalbloat

そういえば現在のBoost.ScopeGuardはキャプチャ方法指定できるようになってるから更に複雑になっている

2012-03-19 02:54:03
Akso de la Malbono @Cryolite

@decimalbloat あぁ,あれは規格違反です(キリッ それにあれの目標は increment を expression でやってしまうことで,さっきのは block-declaration なので強力さが桁違いです.

2012-03-19 02:56:05
Akso de la Malbono @Cryolite

@decimalbloat C++11 による scope guard のエミュレーションなら block-declaration を使って構わないので,使える闇資源が増えますし他にもまだ埋もれている闇鉱脈があると思うのでどんどん掘り出していきましょう.

2012-03-19 02:58:57
でちまるさん(実際かわいい) @decimalbloat

@Cryolite なるほど…まぁ「あのカウンタどうだっけ」→「規格違反です」というやりとりもこれで二回目ですが.

2012-03-19 03:02:22
前へ 1 2 ・・ 5 次へ