C++ で longjmp() 関数を使ってはならない

longjmp() 関数を使うと C でも例外処理っぽいことができるわけだが、これは、間違っても C++ プログラム中では使ってはならない。まあ、C++ には本物の例外処理があるので使うわけもないのだが、C との混合プログラミング*1の際などには注意を要する。
問題は、longjmp() の呼び出しによって消滅するスタック上のオブジェクトのデストラクタが呼ばれない、ということだ。例外送出に伴うスタック巻き戻しではスタック上のオブジェクトが解体されるが、longjmp() にはこれがない。いや、デストラクタが呼び出されないどころか、そもそもそういう事態での C++ プログラムの挙動は不定である:

C++ 標準*2 ― 18.7 の 4
The function signature longjmp(jmp_buf jbuf, int val) has more restricted behavior in this International Standard. If any automatic objects would be destroyed by a thrown exception transferring control to another (destination) point in the program, then a call to longjmp(jbuf, val) at the throw point that transfers control to the same (destination) point has undefined behavior.
なんだか間怠っこしい書き方だが、「longjmp() の呼び出しの結果として消滅するスタックにデストラクタが呼び出されるような*3オブジェクトがあったら、プログラムの動作がどうなるかは分からないよ」ということだ。「undefined behavior」なので、それこそ、HDD をフォーマットされても文句は言えない。
現実問題として C++ で RAII を意識しないプログラミングはありえず、したがって、longjmp() 関数の出る幕はない。自己矛盾もいいところの <csetjmp> なんていうヘッダは、間違っても include してはならない。

*1:こういう微妙な問題がつきまとうので、C と C++ の混合プログラミングはできれば避けたい。

*2:ISO/IEC 14882:2003(E)。

*3:規格中の「destroyed」をこう解釈していいのかは、自信がない。