Binary 2.0カンファレンス 2006 で田中さんが発表していた「getcontextの怪」、最初はフーン( ´_ゝ`)と思っていたのだけれど、よくよく考えてみると結構深い話である。

まず、田中さんのサンプルプログラム、よくみると、getcontext()している関数中でローカル変数がvolatileされていない。
んで、さらに困ったことにsetjmp()はC99(JISだとJIS X 3010)の規格で
「ただし対応するsetjmpマクロの呼び出しを含む関数中の、volatile修飾型でない自動記憶域期間をもつオブジェクトの値が、setjmp呼び出しとlongjmp呼び出しの間に変更された場合に不定となる事をのぞく」
と但し書きがあるので、こういうコードは書けない。

JISCのサイトで規格が無料で読めるので興味のある人はドゾ
スキャナで取り込んだと思しき、全ページ画像のクソPDFなので、検索できなくて超使いにくいけどね(苦笑)

んで、困ったことにSingle UNIX Spesification(SUS)のgetcontextの定義ではこのvolatile云々の免罪事項がないらしいんだわ。

※2 Linuxの人は man 3p getcontext で規格定義が読めるらしいよ。便利な世の中になったね♪

でも、この volatile 云々ってのはThe rationale for the C99 standard に書かれているように、そもそも変数がレジスタに乗るかどうかコンパイラしか知らない状況ではライブラリに出来る事なんかねーよハゲ。って事なので、書いてないからvolatileなくても動くように作れよ。と言われてもなかなかツライものがあるのである。

たぶん、唯一の解決策は、setjmp, getcontext呼び出しを含む関数はすべてのローカル変数をvolatileであるかのように扱う。ってやつでgccがやっている対策もコレ(のはず、よく知らないけど)

でも、やっぱりオイラは規格を直すべきだとオモタですよ




不能王と宣言します
定義不能! ランキング!