Unwind-safe scope(failure)
@decimalbloat std::uncaught_exception を使って判定するのはまずいというところまでが昨日の結論だったので, scope(exit) のみを提供して(全部の副作用が成功したら)それらを無効化する設計にすべきだと思いました.
2012-03-19 02:03:26@decimalbloat 元々(10年くらい前?), C++ における scope guard のエミュレーションはユーザに scope guard の名前を付けさせて,ユーザが個々の scope guard を無効化できるインタフェイスが付いてました.
2012-03-19 02:05:08@decimalbloat なので,元々の scope guard オブジェクトは個々に bool の flag を持っていて,それによって destructor で rollback を起動するかどうかを実行時に分岐してました.
2012-03-19 02:06:58@decimalbloat ただ, SG のほとんどの利用パタンでは個々の SG の有効・無効を制御する必要はなくて「現在のスコープで宣言したものを全部無効化する」か「lexical に見えているものを全部無効化する」かのどちらかで十分だと思います.
2012-03-19 02:10:00@decimalbloat さっきうpしたものは「あるスコープで宣言された SG だけを一斉に無効化する」というものです.内側の scope で return するケースもあるので「lexical に見えている SG を全部無効化」も追加する必要があると思います.
2012-03-19 02:11:59@decimalbloat で,元々の設計に立ち戻って,全部の SG の発動フラグをスレッドローカルな flag 1つにまとめて,その flag を触るだけで複数の SG の発動を一斉に制御すればどうかと.スレッドローカルにしてあるのは race-free にするためです.
2012-03-19 02:15:49@decimalbloat あと「そのブロックスコープで宣言されたものだけ無効化の対象とする」を実現するために,あるブロックスコープで初めて宣言されたものだけにマーキングする技法を使っています.基本的なアイデアを説明すると http://t.co/aIxuZgNS
2012-03-19 02:24:15@Cryolite とても長い説明ありがとうございました.ところでスコープ単位かもしくはlexicalに見える範囲を単位として制御するのであれば,フラグは別にグローバル変数じゃなくてローカル変数でもいいと思うのですがどうでしょう?
2012-03-19 02:34:39@Cryolite フラグとなるローカル変数はスコープまたはlexicalに見える範囲において一度だけ宣言します(もちろんユーザにそのフラグを明示的に書かせるわけではなく,SGの構文に含めます)
2012-03-19 02:36:27@decimalbloat はい.もちろんそうなんですが,ユーザにそのローカル変数を一切見せることなく,しかも無効化のときに触る,というのは1日瞑想しましたが私の非力な闇魔力では詠唱できませんでした.すいません.
2012-03-19 02:38:28@Cryolite 今のBoost.ScopeGuardはlexicalに見える範囲において一度だけ変数宣言となるような技巧が使われているので,それ参考にしたらいけそうだと思ったのです.
2012-03-19 02:41:06@decimalbloat 同じ preprocess token を使いながら,その内部にオブジェクトの宣言・定義をあるスコープ内できっかり一度だけ行う闇魔法を織り込む,ということになると思いますが私には詠唱しきれませんでした.(関数の宣言ならもちろん複数回できますが)
2012-03-19 02:41:28@decimalbloat あと関係ないですが,あるブロックスコープ内で異なる番号を連番で振っていく闇魔法があるので使える場面があったら使ってやってください. http://t.co/g7mh37iv SG を部分的に無効化するために使えるかと思ってたんですが要らなさそうなので.
2012-03-19 02:45:05@Cryolite 大分前の日記にFOREACH書いてましたよね.そこでも似たようなことやってましたよ.
2012-03-19 02:53:34そういえば現在のBoost.ScopeGuardはキャプチャ方法指定できるようになってるから更に複雑になっている
2012-03-19 02:54:03@decimalbloat あぁ,あれは規格違反です(キリッ それにあれの目標は increment を expression でやってしまうことで,さっきのは block-declaration なので強力さが桁違いです.
2012-03-19 02:56:05@decimalbloat C++11 による scope guard のエミュレーションなら block-declaration を使って構わないので,使える闇資源が増えますし他にもまだ埋もれている闇鉱脈があると思うのでどんどん掘り出していきましょう.
2012-03-19 02:58:57@Cryolite なるほど…まぁ「あのカウンタどうだっけ」→「規格違反です」というやりとりもこれで二回目ですが.
2012-03-19 03:02:22