goto では、デストラクタは呼ばれる

僕は、goto が嫌いだ。まあ、好きな人なんていないとは思うが。一度でも“今は亡き前任者の goto”に泣かされたことがあれば、全ての goto 文は「goto HELL;」にしか見えなくなるはずだ。“goto 文の全てが悪いわけではない”、“多重ループからの脱出には goto が分かりやすい”、といった主張には概ね賛成だが、それでも、「いい goto と悪い goto を見分けるぐらいなら、一律禁止の方が全体的作業効率はいい」というのが正直な感想だ。弊害が多すぎる上に無ければ無いで大して困らない((大抵の goto は、return でうまく書き直せる。その結果として関数がほどよく分割されて全体的な読みやすさが向上することもよくある。))もの、それが goto
このように goto を毛嫌いしている僕としては、goto のない正しい未来を正当化する理由を常に探しているわけで、longjmp() はスタックを正しく巻き戻せないので C++ 的には使えない、ということを知った刹那、「じゃあ、goto もダメなんじゃないの((longjmp() 関数は、“関数間での goto”と説明されることもよくある。個人的には goto というよりかは break だと思うが、「break など goto に過ぎぬわっ!!」と言われる方もいらっしゃる。))?」という邪な考えが頭をよぎった。
ところが、残念なことに、C++goto は、それによってスコープから外れたオブジェクトのデストラクタを正しく呼び出してしまう:

C++ 標準*1 ― 6.6

Jump statements unconditionally transfer control.

jump-statement:
    break ;
    continue ;
    return expressionopt ;
    goto identifier ;

On exit from a scope (however accomplished), destructors (12.4) are called for all constructed objects with automatic storage duration (3.7.2) (named objects or temporaries) that are declared in that scope, in the reverse order of their declaration.

というわけで、goto を葬り去るのには失敗したが、よく考えたら、最近は goto を書こうという人をそもそも見かけない。

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